core: run ruff format
This commit is contained in:
parent
7130effb58
commit
166db21812
821 changed files with 82905 additions and 84121 deletions
|
|
@ -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
|
||||
|
|
|
|||
15
conftest.py
15
conftest.py
|
|
@ -16,13 +16,13 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
import pytest # noqa
|
||||
import pytest # noqa
|
||||
|
||||
# keep the imports to have a toplevel conftest.py but still importable from EE edition
|
||||
from rhodecode.tests.conftest_common import ( # noqa
|
||||
from rhodecode.tests.conftest_common import ( # noqa
|
||||
pytest_generate_tests,
|
||||
pytest_runtest_makereport,
|
||||
pytest_addoption
|
||||
pytest_addoption,
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -36,13 +36,12 @@ pytest_plugins = [
|
|||
|
||||
|
||||
def pytest_configure(config):
|
||||
from rhodecode.config import patches # noqa
|
||||
from rhodecode.config import patches # noqa
|
||||
|
||||
|
||||
def pytest_collection_modifyitems(session, config, items):
|
||||
# nottest marked, compare nose, used for transition from nose to pytest
|
||||
remaining = [
|
||||
i for i in items if getattr(i.obj, '__test__', True)]
|
||||
remaining = [i for i in items if getattr(i.obj, "__test__", True)]
|
||||
items[:] = remaining
|
||||
|
||||
# NOTE(marcink): custom test ordering, db tests and vcstests are slowest and should
|
||||
|
|
@ -50,9 +49,9 @@ def pytest_collection_modifyitems(session, config, items):
|
|||
def sorter(item):
|
||||
pos = 0
|
||||
key = item._nodeid
|
||||
if key.startswith('rhodecode/tests/database'):
|
||||
if key.startswith("rhodecode/tests/database"):
|
||||
pos = 1
|
||||
elif key.startswith('rhodecode/tests/vcs_operations'):
|
||||
elif key.startswith("rhodecode/tests/vcs_operations"):
|
||||
pos = 2
|
||||
|
||||
return pos
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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,))
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 = []
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue