core: run ruff format

This commit is contained in:
RhodeCode Admin 2025-01-13 17:47:37 +01:00
parent 7130effb58
commit 166db21812
821 changed files with 82905 additions and 84121 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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 '<Optional:{}>'.format(None) == repr(option1)
assert "<Optional:{}>".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 '<OptionalAttr:apiuser>' == repr(oattr1)
oattr1 = OAttr("apiuser")
assert "<OptionalAttr:apiuser>" == 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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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'
# assert call_args[2] == 'new_method'

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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': '<RequiredType>',
'comment_type': "<Optional:'note'>",
'commit_id': '<RequiredType>',
'extra_recipients': '<Optional:[]>',
'message': '<RequiredType>',
'repoid': '<RequiredType>',
'request': '<RequiredType>',
'resolves_comment_id': '<Optional:None>',
'status': '<Optional:None>',
'userid': '<Optional:<OptionalAttr:apiuser>>',
'send_email': '<Optional:True>'}]
expected = [
"comment_commit",
{
"apiuser": "<RequiredType>",
"comment_type": "<Optional:'note'>",
"commit_id": "<RequiredType>",
"extra_recipients": "<Optional:[]>",
"message": "<RequiredType>",
"repoid": "<RequiredType>",
"request": "<RequiredType>",
"resolves_comment_id": "<Optional:None>",
"status": "<Optional:None>",
"userid": "<Optional:<OptionalAttr:apiuser>>",
"send_email": "<Optional:True>",
},
]
assert_ok(id_, expected, given=response.body)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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 <class 'int'> 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)

View file

@ -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)

View file

@ -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)

View file

@ -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 = []

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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"]

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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))

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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,)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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()
)

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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 '<OptionalAttr:%s>' % self.attr_name
return "<OptionalAttr:%s>" % self.attr_name
def __call__(self):
return self
@ -73,7 +72,7 @@ class Optional(object):
self.type_ = type_
def __repr__(self):
return '<Optional:%s>' % self.type_.__repr__()
return "<Optional:%s>" % 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,
}

View file

@ -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)
return get_user_locks(request=request, apiuser=apiuser, userid=userid)

View file

@ -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,))
log.exception("Error occured during gist deletion")
raise JSONRPCError("failed to delete gist ID:%s" % (gist.gist_access_id,))

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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)
)

View file

@ -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)

View file

@ -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 = '<RequiredType>'
default_empty = "<RequiredType>"
# 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}

View file

@ -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()

View file

@ -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 = []

View file

@ -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)
)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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):

File diff suppressed because it is too large Load diff

View file

@ -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")

View file

@ -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("""<span class="error-message">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(
"""<span class="error-message">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"

View file

@ -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

View file

@ -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

View file

@ -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')
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")

View file

@ -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 <a href="/{}">{}</a>'.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)

Some files were not shown because too many files have changed in this diff Show more