##// END OF EJS Templates
fix(mercurial): dropped support for depreacted hgsubversion fixes RCCE-12
fix(mercurial): dropped support for depreacted hgsubversion fixes RCCE-12

File last commit:

r5093:525812a8 default
r5250:c24343a3 default
Show More
repo_forks.py
252 lines | 9.5 KiB | text/x-python | PythonLexer
copyrights: updated for 2023
r5088 # Copyright (C) 2011-2023 RhodeCode GmbH
forks: moved pylons code into pyramid.
r1988 #
# 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
# (only), as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
import logging
import datetime
import formencode
apps: cleanup imports
r2080 import formencode.htmlfill
from pyramid.httpexceptions import HTTPFound
application: not use config.scan(), and replace all @add_view decorator into a explicit add_view call for faster app start.
r4610
forks: moved pylons code into pyramid.
r1988 from pyramid.renderers import render
from pyramid.response import Response
permissions: flush cache when creating a new fork.
r2874 from rhodecode import events
forks: moved pylons code into pyramid.
r1988 from rhodecode.apps._base import RepoAppView, DataGridAppView
from rhodecode.lib.auth import (
LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous,
HasRepoPermissionAny, HasPermissionAnyDecorator, CSRFRequired)
import rhodecode.lib.helpers as h
core: multiple fixes to unicode vs str usage...
r5065 from rhodecode.lib.str_utils import safe_str
celery: celery 4.X support. Fixes #4169...
r2359 from rhodecode.lib.celerylib.utils import get_task_id
apps: cleanup imports
r2080 from rhodecode.model.db import coalesce, or_, Repository, RepoGroup
permissions: properly flush user cache permissions in more cases of permission changes....
r3824 from rhodecode.model.permission import PermissionModel
forks: moved pylons code into pyramid.
r1988 from rhodecode.model.repo import RepoModel
from rhodecode.model.forms import RepoForkForm
from rhodecode.model.scm import ScmModel, RepoGroupList
log = logging.getLogger(__name__)
class RepoForksView(RepoAppView, DataGridAppView):
def load_default_context(self):
c = self._get_local_tmpl_context(include_app_defaults=True)
c.rhodecode_repo = self.rhodecode_vcs_repo
acl_groups = RepoGroupList(
RepoGroup.query().all(),
perm_set=['group.write', 'group.admin'])
c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
core: multiple fixes to unicode vs str usage...
r5065 c.repo_groups_choices = list(map(lambda k: safe_str(k[0]), c.repo_groups))
landing-rev: fixes #4102, use branches instead of landing tip refs by default....
r3881
forks: moved pylons code into pyramid.
r1988 c.personal_repo_group = c.rhodecode_user.personal_repo_group
return c
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
def repo_forks_show_all(self):
c = self.load_default_context()
return self._get_template_context(c)
@LoginRequired()
@HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
def repo_forks_data(self):
_ = self.request.translate
pylons: fixed code and test suite after removal of pylons.
r2358 self.load_default_context()
forks: moved pylons code into pyramid.
r1988 column_map = {
'fork_name': 'repo_name',
'fork_date': 'created_on',
'last_activity': 'updated_on'
}
draw, start, limit = self._extract_chunk(self.request)
search_q, order_by, order_dir = self._extract_ordering(
self.request, column_map=column_map)
acl_check = HasRepoPermissionAny(
'repository.read', 'repository.write', 'repository.admin')
repo_id = self.db_repo.repo_id
db: prevent empty IN queries that generally are performance problem, and triggers sql warnings.
r2176 allowed_ids = [-1]
forks: moved pylons code into pyramid.
r1988 for f in Repository.query().filter(Repository.fork_id == repo_id):
if acl_check(f.repo_name, 'get forks check'):
allowed_ids.append(f.repo_id)
forks_data_total_count = Repository.query()\
.filter(Repository.fork_id == repo_id)\
.filter(Repository.repo_id.in_(allowed_ids))\
.count()
# json generate
base_q = Repository.query()\
.filter(Repository.fork_id == repo_id)\
.filter(Repository.repo_id.in_(allowed_ids))\
if search_q:
apps: modernize for python3
r5093 like_expression = f'%{safe_str(search_q)}%'
forks: moved pylons code into pyramid.
r1988 base_q = base_q.filter(or_(
Repository.repo_name.ilike(like_expression),
Repository.description.ilike(like_expression),
))
forks_data_total_filtered_count = base_q.count()
sort_col = getattr(Repository, order_by, None)
if sort_col:
if order_dir == 'asc':
# handle null values properly to order by NULL last
if order_by in ['last_activity']:
sort_col = coalesce(sort_col, datetime.date.max)
sort_col = sort_col.asc()
else:
# handle null values properly to order by NULL last
if order_by in ['last_activity']:
sort_col = coalesce(sort_col, datetime.date.min)
sort_col = sort_col.desc()
base_q = base_q.order_by(sort_col)
base_q = base_q.offset(start).limit(limit)
fork_list = base_q.all()
def fork_actions(fork):
url_link = h.route_path(
'repo_compare',
repo_name=fork.repo_name,
landing-refs: create helpers for landing ref to make clear indication about type/name
r4370 source_ref_type=self.db_repo.landing_ref_type,
source_ref=self.db_repo.landing_ref_name,
target_ref_type=self.db_repo.landing_ref_type,
target_ref=self.db_repo.landing_ref_name,
forks: moved pylons code into pyramid.
r1988 _query=dict(merge=1, target_repo=f.repo_name))
return h.link_to(_('Compare fork'), url_link, class_='btn-link')
def fork_name(fork):
return h.link_to(fork.repo_name,
h.route_path('repo_summary', repo_name=fork.repo_name))
forks_data = []
for fork in fork_list:
forks_data.append({
"username": h.gravatar_with_user(self.request, fork.user.username),
"fork_name": fork_name(fork),
forks: prevent XSS in datagrid of forks data.
r2996 "description": fork.description_safe,
forks: moved pylons code into pyramid.
r1988 "fork_date": h.age_component(fork.created_on, time_is_local=True),
"last_activity": h.format_date(fork.updated_on),
"action": fork_actions(fork),
})
data = ({
'draw': draw,
'data': forks_data,
'recordsTotal': forks_data_total_count,
'recordsFiltered': forks_data_total_filtered_count,
})
return data
@LoginRequired()
@NotAnonymous()
permissions: use constant for fork enable/disable
r4663 @HasPermissionAnyDecorator('hg.admin', PermissionModel.FORKING_ENABLED)
forks: moved pylons code into pyramid.
r1988 @HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
def repo_fork_new(self):
c = self.load_default_context()
defaults = RepoModel()._get_defaults(self.db_repo_name)
# alter the description to indicate a fork
defaults['description'] = (
apps: modernize for python3
r5093 'fork of repository: {} \n{}'.format(
forks: moved pylons code into pyramid.
r1988 defaults['repo_name'], defaults['description']))
# add suffix to fork
defaults['repo_name'] = '%s-fork' % defaults['repo_name']
data = render('rhodecode:templates/forks/fork.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=defaults,
encoding="UTF-8",
force_defaults=False
)
return Response(html)
@LoginRequired()
@NotAnonymous()
permissions: use constant for fork enable/disable
r4663 @HasPermissionAnyDecorator('hg.admin', PermissionModel.FORKING_ENABLED)
forks: moved pylons code into pyramid.
r1988 @HasRepoPermissionAnyDecorator(
'repository.read', 'repository.write', 'repository.admin')
@CSRFRequired()
def repo_fork_create(self):
_ = self.request.translate
c = self.load_default_context()
landing-rev: fixes #4102, use branches instead of landing tip refs by default....
r3881 _form = RepoForkForm(self.request.translate,
old_data={'repo_type': self.db_repo.repo_type},
repo_groups=c.repo_groups_choices)()
repo-forks: security, fix issue when forging fork_repo_id could allow reading...
r2172 post_data = dict(self.request.POST)
# forbid injecting other repo by forging a request
post_data['fork_parent_id'] = self.db_repo.repo_id
forks: fixed forking with new landing rev....
r3969 post_data['landing_rev'] = self.db_repo._landing_revision
repo-forks: security, fix issue when forging fork_repo_id could allow reading...
r2172
forks: moved pylons code into pyramid.
r1988 form_result = {}
task_id = None
try:
repo-forks: security, fix issue when forging fork_repo_id could allow reading...
r2172 form_result = _form.to_python(post_data)
permissions: handle more cases for invalidating permission caches...
r3411 copy_permissions = form_result.get('copy_permissions')
forks: moved pylons code into pyramid.
r1988 # create fork is done sometimes async on celery, db transaction
# management is handled there.
task = RepoModel().create_fork(
form_result, c.rhodecode_user.user_id)
celery: celery 4.X support. Fixes #4169...
r2359
task_id = get_task_id(task)
forks: moved pylons code into pyramid.
r1988 except formencode.Invalid as errors:
apps: removed deprecated usage of c.repo_info
r2081 c.rhodecode_db_repo = self.db_repo
forks: moved pylons code into pyramid.
r1988
data = render('rhodecode:templates/forks/fork.mako',
self._get_template_context(c), self.request)
html = formencode.htmlfill.render(
data,
defaults=errors.value,
errors=errors.error_dict or {},
prefix_error=False,
encoding="UTF-8",
force_defaults=False
)
return Response(html)
except Exception:
log.exception(
apps: modernize for python3
r5093 'Exception while trying to fork the repository %s', self.db_repo_name)
permissions: handle more cases for invalidating permission caches...
r3411 msg = _('An error occurred during repository forking %s') % (self.db_repo_name, )
forks: moved pylons code into pyramid.
r1988 h.flash(msg, category='error')
permissions: handle more cases for invalidating permission caches...
r3411 raise HTTPFound(h.route_path('home'))
forks: moved pylons code into pyramid.
r1988
repo_name = form_result.get('repo_name_full', self.db_repo_name)
permissions: flush cache when creating a new fork.
r2874
permissions: handle more cases for invalidating permission caches...
r3411 affected_user_ids = [self._rhodecode_user.user_id]
if copy_permissions:
permissions: flush permissions correctly for forks/repos when celery is used.
r3413 # permission flush is done in repo creating
pass
permissions: handle more cases for invalidating permission caches...
r3411
permissions: properly flush user cache permissions in more cases of permission changes....
r3824 PermissionModel().trigger_permission_flush(affected_user_ids)
permissions: flush cache when creating a new fork.
r2874
forks: moved pylons code into pyramid.
r1988 raise HTTPFound(
permissions: handle more cases for invalidating permission caches...
r3411 h.route_path('repo_creating', repo_name=repo_name,
forks: moved pylons code into pyramid.
r1988 _query=dict(task_id=task_id)))