diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py
--- a/rhodecode/apps/repository/__init__.py
+++ b/rhodecode/apps/repository/__init__.py
@@ -21,6 +21,11 @@
def includeme(config):
+ # Settings
+ config.add_route(
+ name='edit_repo',
+ pattern='/{repo_name:.*?[^/]}/settings', repo_route=True)
+
config.add_route(
name='repo_maintenance',
pattern='/{repo_name:.*?[^/]}/maintenance', repo_route=True)
@@ -29,7 +34,6 @@ def includeme(config):
name='repo_maintenance_execute',
pattern='/{repo_name:.*?[^/]}/maintenance/execute', repo_route=True)
-
# Strip
config.add_route(
name='strip',
diff --git a/rhodecode/apps/repository/views/repo_settings.py b/rhodecode/apps/repository/views/repo_settings.py
new file mode 100644
--- /dev/null
+++ b/rhodecode/apps/repository/views/repo_settings.py
@@ -0,0 +1,178 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (C) 2011-2017 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
+# (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 .
+#
+# 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 deform
+from pyramid.httpexceptions import HTTPFound
+from pyramid.view import view_config
+
+from rhodecode.apps._base import RepoAppView
+from rhodecode.forms import RcForm
+from rhodecode.lib import helpers as h
+from rhodecode.lib import audit_logger
+from rhodecode.lib.auth import (
+ LoginRequired, HasRepoPermissionAnyDecorator,
+ HasRepoPermissionAllDecorator, CSRFRequired)
+from rhodecode.model.db import RepositoryField, RepoGroup
+from rhodecode.model.meta import Session
+from rhodecode.model.repo import RepoModel
+from rhodecode.model.scm import RepoGroupList, ScmModel
+from rhodecode.model.validation_schema.schemas import repo_schema
+
+log = logging.getLogger(__name__)
+
+
+class RepoSettingsView(RepoAppView):
+
+ def load_default_context(self):
+ c = self._get_local_tmpl_context()
+
+ # TODO(marcink): remove repo_info and use c.rhodecode_db_repo instead
+ c.repo_info = self.db_repo
+
+ acl_groups = RepoGroupList(
+ RepoGroup.query().all(),
+ perm_set=['group.write', 'group.admin'])
+ c.repo_groups = RepoGroup.groups_choices(groups=acl_groups)
+ c.repo_groups_choices = map(lambda k: k[0], c.repo_groups)
+
+ # in case someone no longer have a group.write access to a repository
+ # pre fill the list with this entry, we don't care if this is the same
+ # but it will allow saving repo data properly.
+ repo_group = self.db_repo.group
+ if repo_group and repo_group.group_id not in c.repo_groups_choices:
+ c.repo_groups_choices.append(repo_group.group_id)
+ c.repo_groups.append(RepoGroup._generate_choice(repo_group))
+
+ if c.repository_requirements_missing or self.rhodecode_vcs_repo is None:
+ # we might be in missing requirement state, so we load things
+ # without touching scm_instance()
+ c.landing_revs_choices, c.landing_revs = \
+ ScmModel().get_repo_landing_revs()
+ else:
+ c.landing_revs_choices, c.landing_revs = \
+ ScmModel().get_repo_landing_revs(self.db_repo)
+
+ c.personal_repo_group = c.auth_user.personal_repo_group
+ c.repo_fields = RepositoryField.query()\
+ .filter(RepositoryField.repository == self.db_repo).all()
+
+ self._register_global_c(c)
+ return c
+
+ def _get_schema(self, c, old_values=None):
+ return repo_schema.RepoSettingsSchema().bind(
+ repo_type_options=[self.db_repo.repo_type],
+ repo_ref_options=c.landing_revs_choices,
+ repo_ref_items=c.landing_revs,
+ repo_repo_group_options=c.repo_groups_choices,
+ repo_repo_group_items=c.repo_groups,
+ # user caller
+ user=self._rhodecode_user,
+ old_values=old_values
+ )
+
+ @LoginRequired()
+ @HasRepoPermissionAnyDecorator('repository.admin')
+ @view_config(
+ route_name='edit_repo', request_method='GET',
+ renderer='rhodecode:templates/admin/repos/repo_edit.mako')
+ def edit_settings(self):
+ c = self.load_default_context()
+ c.active = 'settings'
+
+ defaults = RepoModel()._get_defaults(self.db_repo_name)
+ defaults['repo_owner'] = defaults['user']
+ defaults['repo_landing_commit_ref'] = defaults['repo_landing_rev']
+
+ schema = self._get_schema(c)
+ c.form = RcForm(schema, appstruct=defaults)
+ return self._get_template_context(c)
+
+ @LoginRequired()
+ @HasRepoPermissionAllDecorator('repository.admin')
+ @CSRFRequired()
+ @view_config(
+ route_name='edit_repo', request_method='POST',
+ renderer='rhodecode:templates/admin/repos/repo_edit.mako')
+ def edit_settings_update(self):
+ _ = self.request.translate
+ c = self.load_default_context()
+ c.active = 'settings'
+ old_repo_name = self.db_repo_name
+
+ old_values = self.db_repo.get_api_data()
+ schema = self._get_schema(c, old_values=old_values)
+
+ c.form = RcForm(schema)
+ pstruct = self.request.POST.items()
+ pstruct.append(('repo_type', self.db_repo.repo_type))
+ try:
+ schema_data = c.form.validate(pstruct)
+ except deform.ValidationFailure as err_form:
+ return self._get_template_context(c)
+
+ # data is now VALID, proceed with updates
+ # save validated data back into the updates dict
+ validated_updates = dict(
+ repo_name=schema_data['repo_group']['repo_name_without_group'],
+ repo_group=schema_data['repo_group']['repo_group_id'],
+
+ user=schema_data['repo_owner'],
+ repo_description=schema_data['repo_description'],
+ repo_private=schema_data['repo_private'],
+ clone_uri=schema_data['repo_clone_uri'],
+ repo_landing_rev=schema_data['repo_landing_commit_ref'],
+ repo_enable_statistics=schema_data['repo_enable_statistics'],
+ repo_enable_locking=schema_data['repo_enable_locking'],
+ repo_enable_downloads=schema_data['repo_enable_downloads'],
+ )
+ # detect if CLONE URI changed, if we get OLD means we keep old values
+ if schema_data['repo_clone_uri_change'] == 'OLD':
+ validated_updates['clone_uri'] = self.db_repo.clone_uri
+
+ # use the new full name for redirect
+ new_repo_name = schema_data['repo_group']['repo_name_with_group']
+
+ # save extra fields into our validated data
+ for key, value in pstruct:
+ if key.startswith(RepositoryField.PREFIX):
+ validated_updates[key] = value
+
+ try:
+ RepoModel().update(self.db_repo, **validated_updates)
+ ScmModel().mark_for_invalidation(new_repo_name)
+
+ audit_logger.store(
+ 'repo.edit', action_data={'old_data': old_values},
+ user=self._rhodecode_user, repo=self.db_repo)
+
+ Session().commit()
+
+ h.flash(_('Repository {} updated successfully').format(
+ old_repo_name), category='success')
+ except Exception:
+ log.exception("Exception during update of repository")
+ h.flash(_('Error occurred during update of repository {}').format(
+ old_repo_name), category='error')
+
+ raise HTTPFound(
+ self.request.route_path('edit_repo', repo_name=new_repo_name))
diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -200,10 +200,6 @@ def make_map(config):
action='index', conditions={'method': ['GET']})
m.connect('new_repo', '/create_repository', jsroute=True,
action='create_repository', conditions={'method': ['GET']})
- m.connect('/repos/{repo_name}',
- action='update', conditions={'method': ['PUT'],
- 'function': check_repo},
- requirements=URL_NAME_REQUIREMENTS)
m.connect('delete_repo', '/repos/{repo_name}',
action='delete', conditions={'method': ['DELETE']},
requirements=URL_NAME_REQUIREMENTS)
@@ -665,11 +661,6 @@ def make_map(config):
requirements=URL_NAME_REQUIREMENTS)
# repo edit options
- rmap.connect('edit_repo', '/{repo_name}/settings', jsroute=True,
- controller='admin/repos', action='edit',
- conditions={'method': ['GET'], 'function': check_repo},
- requirements=URL_NAME_REQUIREMENTS)
-
rmap.connect('edit_repo_perms', '/{repo_name}/settings/permissions',
jsroute=True,
controller='admin/repos', action='edit_permissions',
diff --git a/rhodecode/controllers/admin/repos.py b/rhodecode/controllers/admin/repos.py
--- a/rhodecode/controllers/admin/repos.py
+++ b/rhodecode/controllers/admin/repos.py
@@ -290,65 +290,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
@auth.CSRFRequired()
- def update(self, repo_name):
- """
- PUT /repos/repo_name: Update an existing item"""
- # Forms posted to this method should contain a hidden field:
- #
- # Or using helpers:
- # h.form(url('repo', repo_name=ID),
- # method='put')
- # url('repo', repo_name=ID)
-
- self.__load_data(repo_name)
- c.active = 'settings'
- c.repo_fields = RepositoryField.query()\
- .filter(RepositoryField.repository == c.repo_info).all()
-
- repo_model = RepoModel()
- changed_name = repo_name
-
- c.personal_repo_group = c.rhodecode_user.personal_repo_group
- # override the choices with extracted revisions !
- repo = Repository.get_by_repo_name(repo_name)
- old_data = {
- 'repo_name': repo_name,
- 'repo_group': repo.group.get_dict() if repo.group else {},
- 'repo_type': repo.repo_type,
- }
- _form = RepoForm(
- edit=True, old_data=old_data, repo_groups=c.repo_groups_choices,
- landing_revs=c.landing_revs_choices, allow_disabled=True)()
-
- try:
- form_result = _form.to_python(dict(request.POST))
- repo = repo_model.update(repo_name, **form_result)
- ScmModel().mark_for_invalidation(repo_name)
- h.flash(_('Repository %s updated successfully') % repo_name,
- category='success')
- changed_name = repo.repo_name
- action_logger(c.rhodecode_user, 'admin_updated_repo',
- changed_name, self.ip_addr, self.sa)
- Session().commit()
- except formencode.Invalid as errors:
- defaults = self.__load_data(repo_name)
- defaults.update(errors.value)
- return htmlfill.render(
- render('admin/repos/repo_edit.mako'),
- defaults=defaults,
- errors=errors.error_dict or {},
- prefix_error=False,
- encoding="UTF-8",
- force_defaults=False)
-
- except Exception:
- log.exception("Exception during update of repository")
- h.flash(_('Error occurred during update of repository %s') \
- % repo_name, category='error')
- return redirect(url('edit_repo', repo_name=changed_name))
-
- @HasRepoPermissionAllDecorator('repository.admin')
- @auth.CSRFRequired()
def delete(self, repo_name):
"""
DELETE /repos/repo_name: Delete an existing item"""
@@ -398,27 +339,8 @@ class ReposController(BaseRepoController
# url('repo', repo_name=ID)
@HasRepoPermissionAllDecorator('repository.admin')
- def edit(self, repo_name):
- """GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
- defaults = self.__load_data(repo_name)
- if 'clone_uri' in defaults:
- del defaults['clone_uri']
-
- c.repo_fields = RepositoryField.query()\
- .filter(RepositoryField.repository == c.repo_info).all()
- c.personal_repo_group = c.rhodecode_user.personal_repo_group
- c.active = 'settings'
- return htmlfill.render(
- render('admin/repos/repo_edit.mako'),
- defaults=defaults,
- encoding="UTF-8",
- force_defaults=False)
-
- @HasRepoPermissionAllDecorator('repository.admin')
def edit_permissions(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
c.active = 'permissions'
defaults = RepoModel()._get_defaults(repo_name)
@@ -446,7 +368,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
def edit_fields(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
c.repo_fields = RepositoryField.query()\
.filter(RepositoryField.repository == c.repo_info).all()
@@ -493,7 +414,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
def edit_advanced(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
c.default_user_id = User.get_default_user().user_id
c.in_public_journal = UserFollowing.query()\
@@ -638,7 +558,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
def edit_caches_form(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
c.active = 'caches'
@@ -660,7 +579,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
def edit_remote_form(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
c.active = 'remote'
@@ -682,7 +600,6 @@ class ReposController(BaseRepoController
@HasRepoPermissionAllDecorator('repository.admin')
def edit_statistics_form(self, repo_name):
"""GET /repo_name/settings: Form to edit an existing item"""
- # url('edit_repo', repo_name=ID)
c.repo_info = self._load_repo(repo_name)
repo = c.repo_info.scm_instance()
diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py
--- a/rhodecode/model/db.py
+++ b/rhodecode/model/db.py
@@ -2184,7 +2184,7 @@ class RepoGroup(Base, BaseModel):
repo_groups = []
if show_empty_group:
- repo_groups = [('-1', u'-- %s --' % _('No parent'))]
+ repo_groups = [(-1, u'-- %s --' % _('No parent'))]
repo_groups.extend([cls._generate_choice(x) for x in groups])
diff --git a/rhodecode/model/repo.py b/rhodecode/model/repo.py
--- a/rhodecode/model/repo.py
+++ b/rhodecode/model/repo.py
@@ -333,12 +333,6 @@ class RepoModel(BaseModel):
val = kwargs[k]
if strip:
k = remove_prefix(k, 'repo_')
- if k == 'clone_uri':
- from rhodecode.model.validators import Missing
- _change = kwargs.get('clone_uri_change')
- if _change in [Missing, 'OLD']:
- # we don't change the value, so use original one
- val = cur_repo.clone_uri
setattr(cur_repo, k, val)
diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js
--- a/rhodecode/public/js/rhodecode/routes.js
+++ b/rhodecode/public/js/rhodecode/routes.js
@@ -24,7 +24,6 @@ function registerRCRoutes() {
pyroutes.register('repo_refs_changelog_data', '/%(repo_name)s/refs-data-changelog', ['repo_name']);
pyroutes.register('repo_default_reviewers_data', '/%(repo_name)s/default-reviewers', ['repo_name']);
pyroutes.register('changeset_home', '/%(repo_name)s/changeset/%(revision)s', ['repo_name', 'revision']);
- pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
pyroutes.register('edit_repo_perms', '/%(repo_name)s/settings/permissions', ['repo_name']);
pyroutes.register('changeset_comment', '/%(repo_name)s/changeset/%(revision)s/comment', ['repo_name', 'revision']);
pyroutes.register('changeset_comment_preview', '/%(repo_name)s/changeset/comment/preview', ['repo_name']);
@@ -98,6 +97,7 @@ function registerRCRoutes() {
pyroutes.register('user_group_autocomplete_data', '/_user_groups', []);
pyroutes.register('repo_list_data', '/_repos', []);
pyroutes.register('goto_switcher_data', '/_goto_data', []);
+ pyroutes.register('edit_repo', '/%(repo_name)s/settings', ['repo_name']);
pyroutes.register('repo_maintenance', '/%(repo_name)s/maintenance', ['repo_name']);
pyroutes.register('repo_maintenance_execute', '/%(repo_name)s/maintenance/execute', ['repo_name']);
pyroutes.register('strip', '/%(repo_name)s/strip', ['repo_name']);
diff --git a/rhodecode/templates/admin/integrations/form.mako b/rhodecode/templates/admin/integrations/form.mako
--- a/rhodecode/templates/admin/integrations/form.mako
+++ b/rhodecode/templates/admin/integrations/form.mako
@@ -3,7 +3,7 @@
<%def name="breadcrumbs_links()">
%if c.repo:
- ${h.link_to('Settings',h.url('edit_repo', repo_name=c.repo.repo_name))}
+ ${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
»
${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
»
diff --git a/rhodecode/templates/admin/integrations/list.mako b/rhodecode/templates/admin/integrations/list.mako
--- a/rhodecode/templates/admin/integrations/list.mako
+++ b/rhodecode/templates/admin/integrations/list.mako
@@ -3,7 +3,7 @@
<%def name="breadcrumbs_links()">
%if c.repo:
- ${h.link_to('Settings',h.url('edit_repo', repo_name=c.repo.repo_name))}
+ ${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
%elif c.repo_group:
${h.link_to(_('Admin'),h.url('admin_home'))}
»
diff --git a/rhodecode/templates/admin/integrations/new.mako b/rhodecode/templates/admin/integrations/new.mako
--- a/rhodecode/templates/admin/integrations/new.mako
+++ b/rhodecode/templates/admin/integrations/new.mako
@@ -4,7 +4,7 @@
<%def name="breadcrumbs_links()">
%if c.repo:
- ${h.link_to('Settings',h.url('edit_repo', repo_name=c.repo.repo_name))}
+ ${h.link_to('Settings',h.route_path('edit_repo', repo_name=c.repo.repo_name))}
»
${h.link_to(_('Integrations'),request.route_url(route_name='repo_integrations_home', repo_name=c.repo.repo_name))}
%elif c.repo_group:
diff --git a/rhodecode/templates/admin/repos/repo_edit.mako b/rhodecode/templates/admin/repos/repo_edit.mako
--- a/rhodecode/templates/admin/repos/repo_edit.mako
+++ b/rhodecode/templates/admin/repos/repo_edit.mako
@@ -40,7 +40,7 @@