##// END OF EJS Templates
vcs: Minimal change to expose the shadow repository...
vcs: Minimal change to expose the shadow repository Based on my original research, this was the "minimal" starting point. It shows that three concepts are needed for the "repo_name": * From the security standpoint we think of the shadow repository having the same ACL as the target repository of the pull request. This is because the pull request itself is considered to be a part of the target repository. Out of this thought, the variable "acl_repo_name" is used whenever we want to check permissions or when we need the database configuration of the repository. An alternative name would have been "db_repo_name", but the usage for ACL checking is the most important one. * From the web interaction perspective, we need the URL which was originally used to get to the repository. This is because based on this base URL commands can be identified. Especially for Git this is important, so that the commands are correctly recognized. Since the URL is in the focus, this is called "url_repo_name". * Finally we have to deal with the repository on the file system. This is what the VCS layer deal with normally, so this name is called "vcs_repo_name". The original repository interaction is a special case where all three names are the same. When interacting with a pull request, these three names are typically all different. This change is minimal in a sense that it just makes the interaction with a shadow repository barely work, without checking any special constraints yet. This was the starting point for further work on this topic.

File last commit:

r873:930d1a1f default
r887:175782be default
Show More
forms.py
551 lines | 20.9 KiB | text/x-python | PythonLexer
project: added all source files and assets
r1 # -*- coding: utf-8 -*-
# Copyright (C) 2010-2016 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 <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/
"""
this is forms validation classes
http://formencode.org/module-formencode.validators.html
for list off all availible validators
we can create our own validators
The table below outlines the options which can be used in a schema in addition to the validators themselves
pre_validators [] These validators will be applied before the schema
chained_validators [] These validators will be applied after the schema
allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present
filter_extra_fields False If True, then keys that aren't associated with a validator are removed
if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value.
ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already
<name> = formencode.validators.<name of validator>
<name> must equal form name
list=[1,2,3,4,5]
for SELECT use formencode.All(OneOf(list), Int())
"""
dan
forms: add deform for integration settings forms
r518 import deform
dan
deform: use pypi deform library and add helpers to deform scope directly...
r519 import logging
import formencode
dan
forms: add deform for integration settings forms
r518 from pkg_resources import resource_filename
dan
deform: use pypi deform library and add helpers to deform scope directly...
r519 from formencode import All, Pipe
from pylons.i18n.translation import _
from rhodecode import BACKENDS
from rhodecode.lib import helpers
from rhodecode.model import validators as v
log = logging.getLogger(__name__)
dan
forms: add deform for integration settings forms
r518
deform_templates = resource_filename('deform', 'templates')
rhodecode_templates = resource_filename('rhodecode', 'templates/forms')
search_path = (rhodecode_templates, deform_templates)
dan
deform: use pypi deform library and add helpers to deform scope directly...
r519
class RhodecodeFormZPTRendererFactory(deform.ZPTRendererFactory):
""" Subclass of ZPTRendererFactory to add rhodecode context variables """
def __call__(self, template_name, **kw):
kw['h'] = helpers
return self.load(template_name)(**kw)
dan
forms: add deform for integration settings forms
r518
dan
deform: use pypi deform library and add helpers to deform scope directly...
r519 form_renderer = RhodecodeFormZPTRendererFactory(search_path)
deform.Form.set_default_renderer(form_renderer)
project: added all source files and assets
r1
def LoginForm():
class _LoginForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
username = v.UnicodeString(
strip=True,
min=1,
not_empty=True,
messages={
'empty': _(u'Please enter a login'),
'tooShort': _(u'Enter a value %(min)i characters long or more')
}
)
password = v.UnicodeString(
strip=False,
min=3,
not_empty=True,
messages={
'empty': _(u'Please enter a password'),
'tooShort': _(u'Enter %(min)i characters or more')}
)
remember = v.StringBoolean(if_missing=False)
chained_validators = [v.ValidAuth()]
return _LoginForm
def UserForm(edit=False, available_languages=[], old_data={}):
class _UserForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
username = All(v.UnicodeString(strip=True, min=1, not_empty=True),
v.ValidUsername(edit, old_data))
if edit:
new_password = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=False)
)
password_confirmation = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=False),
)
admin = v.StringBoolean(if_missing=False)
else:
password = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=True)
)
password_confirmation = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=False)
)
password_change = v.StringBoolean(if_missing=False)
create_repo_group = v.StringBoolean(if_missing=False)
active = v.StringBoolean(if_missing=False)
firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
extern_name = v.UnicodeString(strip=True)
extern_type = v.UnicodeString(strip=True)
language = v.OneOf(available_languages, hideList=False,
testValueList=True, if_missing=None)
chained_validators = [v.ValidPasswordsMatch()]
return _UserForm
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 def UserGroupForm(edit=False, old_data=None, available_members=None,
allow_disabled=False):
old_data = old_data or {}
available_members = available_members or []
project: added all source files and assets
r1 class _UserGroupForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
users_group_name = All(
v.UnicodeString(strip=True, min=1, not_empty=True),
v.ValidUserGroup(edit, old_data)
)
user_group_description = v.UnicodeString(strip=True, min=1,
not_empty=False)
users_group_active = v.StringBoolean(if_missing=False)
if edit:
users_group_members = v.OneOf(
available_members, hideList=False, testValueList=True,
if_missing=None, not_empty=False
)
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 # this is user group owner
user = All(
v.UnicodeString(not_empty=True),
v.ValidRepoUser(allow_disabled))
project: added all source files and assets
r1 return _UserGroupForm
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 def RepoGroupForm(edit=False, old_data=None, available_groups=None,
can_create_in_root=False, allow_disabled=False):
old_data = old_data or {}
available_groups = available_groups or []
project: added all source files and assets
r1 class _RepoGroupForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
group_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
v.SlugifyName(),)
group_description = v.UnicodeString(strip=True, min=1,
not_empty=False)
group_copy_permissions = v.StringBoolean(if_missing=False)
group_parent_id = v.OneOf(available_groups, hideList=False,
testValueList=True, not_empty=True)
enable_locking = v.StringBoolean(if_missing=False)
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 chained_validators = [
v.ValidRepoGroup(edit, old_data, can_create_in_root)]
project: added all source files and assets
r1
if edit:
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 # this is repo group owner
user = All(
v.UnicodeString(not_empty=True),
v.ValidRepoUser(allow_disabled))
project: added all source files and assets
r1
return _RepoGroupForm
def RegisterForm(edit=False, old_data={}):
class _RegisterForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
username = All(
v.ValidUsername(edit, old_data),
v.UnicodeString(strip=True, min=1, not_empty=True)
)
password = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=True)
)
password_confirmation = All(
v.ValidPassword(),
v.UnicodeString(strip=False, min=6, not_empty=True)
)
active = v.StringBoolean(if_missing=False)
firstname = v.UnicodeString(strip=True, min=1, not_empty=False)
lastname = v.UnicodeString(strip=True, min=1, not_empty=False)
email = All(v.Email(not_empty=True), v.UniqSystemEmail(old_data))
chained_validators = [v.ValidPasswordsMatch()]
return _RegisterForm
def PasswordResetForm():
class _PasswordResetForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
email = All(v.ValidSystemEmail(), v.Email(not_empty=True))
return _PasswordResetForm
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 def RepoForm(edit=False, old_data=None, repo_groups=None, landing_revs=None,
allow_disabled=False):
project: added all source files and assets
r1 old_data = old_data or {}
repo_groups = repo_groups or []
landing_revs = landing_revs or []
supported_backends = BACKENDS.keys()
class _RepoForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
v.SlugifyName())
repo_group = All(v.CanWriteGroup(old_data),
v.OneOf(repo_groups, hideList=True))
repo_type = v.OneOf(supported_backends, required=False,
if_missing=old_data.get('repo_type'))
repo_description = v.UnicodeString(strip=True, min=1, not_empty=False)
repo_private = v.StringBoolean(if_missing=False)
repo_landing_rev = v.OneOf(landing_revs, hideList=True)
repo_copy_permissions = v.StringBoolean(if_missing=False)
clone_uri = All(v.UnicodeString(strip=True, min=1, not_empty=False))
repo_enable_statistics = v.StringBoolean(if_missing=False)
repo_enable_downloads = v.StringBoolean(if_missing=False)
repo_enable_locking = v.StringBoolean(if_missing=False)
if edit:
# this is repo owner
repos, repo groups, user groups: allow to use disabled users in owner field....
r224 user = All(
v.UnicodeString(not_empty=True),
v.ValidRepoUser(allow_disabled))
project: added all source files and assets
r1 clone_uri_change = v.UnicodeString(
not_empty=False, if_missing=v.Missing)
chained_validators = [v.ValidCloneUri(),
v.ValidRepoName(edit, old_data)]
return _RepoForm
def RepoPermsForm():
class _RepoPermsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
chained_validators = [v.ValidPerms(type_='repo')]
return _RepoPermsForm
def RepoGroupPermsForm(valid_recursive_choices):
class _RepoGroupPermsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
recursive = v.OneOf(valid_recursive_choices)
chained_validators = [v.ValidPerms(type_='repo_group')]
return _RepoGroupPermsForm
def UserGroupPermsForm():
class _UserPermsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
chained_validators = [v.ValidPerms(type_='user_group')]
return _UserPermsForm
def RepoFieldForm():
class _RepoFieldForm(formencode.Schema):
filter_extra_fields = True
allow_extra_fields = True
new_field_key = All(v.FieldKey(),
v.UnicodeString(strip=True, min=3, not_empty=True))
new_field_value = v.UnicodeString(not_empty=False, if_missing=u'')
new_field_type = v.OneOf(['str', 'unicode', 'list', 'tuple'],
if_missing='str')
new_field_label = v.UnicodeString(not_empty=False)
new_field_desc = v.UnicodeString(not_empty=False)
return _RepoFieldForm
def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
repo_groups=[], landing_revs=[]):
class _RepoForkForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
repo_name = All(v.UnicodeString(strip=True, min=1, not_empty=True),
v.SlugifyName())
repo_group = All(v.CanWriteGroup(),
v.OneOf(repo_groups, hideList=True))
repo_type = All(v.ValidForkType(old_data), v.OneOf(supported_backends))
description = v.UnicodeString(strip=True, min=1, not_empty=True)
private = v.StringBoolean(if_missing=False)
copy_permissions = v.StringBoolean(if_missing=False)
fork_parent_id = v.UnicodeString()
chained_validators = [v.ValidForkName(edit, old_data)]
landing_rev = v.OneOf(landing_revs, hideList=True)
return _RepoForkForm
def ApplicationSettingsForm():
class _ApplicationSettingsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
rhodecode_title = v.UnicodeString(strip=True, max=40, not_empty=False)
rhodecode_realm = v.UnicodeString(strip=True, min=1, not_empty=True)
rhodecode_pre_code = v.UnicodeString(strip=True, min=1, not_empty=False)
rhodecode_post_code = v.UnicodeString(strip=True, min=1, not_empty=False)
rhodecode_captcha_public_key = v.UnicodeString(strip=True, min=1, not_empty=False)
rhodecode_captcha_private_key = v.UnicodeString(strip=True, min=1, not_empty=False)
return _ApplicationSettingsForm
def ApplicationVisualisationForm():
class _ApplicationVisualisationForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
rhodecode_show_public_icon = v.StringBoolean(if_missing=False)
rhodecode_show_private_icon = v.StringBoolean(if_missing=False)
rhodecode_stylify_metatags = v.StringBoolean(if_missing=False)
rhodecode_repository_fields = v.StringBoolean(if_missing=False)
rhodecode_lightweight_journal = v.StringBoolean(if_missing=False)
rhodecode_dashboard_items = v.Int(min=5, not_empty=True)
rhodecode_admin_grid_items = v.Int(min=5, not_empty=True)
rhodecode_show_version = v.StringBoolean(if_missing=False)
rhodecode_use_gravatar = v.StringBoolean(if_missing=False)
rhodecode_markup_renderer = v.OneOf(['markdown', 'rst'])
rhodecode_gravatar_url = v.UnicodeString(min=3)
rhodecode_clone_uri_tmpl = v.UnicodeString(min=3)
rhodecode_support_url = v.UnicodeString()
rhodecode_show_revision_number = v.StringBoolean(if_missing=False)
rhodecode_show_sha_length = v.Int(min=4, not_empty=True)
return _ApplicationVisualisationForm
class _BaseVcsSettingsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
hooks_changegroup_repo_size = v.StringBoolean(if_missing=False)
hooks_changegroup_push_logger = v.StringBoolean(if_missing=False)
hooks_outgoing_pull_logger = v.StringBoolean(if_missing=False)
extensions_largefiles = v.StringBoolean(if_missing=False)
phases_publish = v.StringBoolean(if_missing=False)
rhodecode_pr_merge_enabled = v.StringBoolean(if_missing=False)
rhodecode_use_outdated_comments = v.StringBoolean(if_missing=False)
Martin Bornhold
settings: Add the 'rebase-merge' setting to VCS base form and VCS settings model.
r358 rhodecode_hg_use_rebase_for_merging = v.StringBoolean(if_missing=False)
project: added all source files and assets
r1
vcs: moved svn proxy settings into vcs related settings...
r754 vcs_svn_proxy_http_requests_enabled = v.StringBoolean(if_missing=False)
vcs_svn_proxy_http_server_url = v.UnicodeString(strip=True, if_missing=None)
project: added all source files and assets
r1
def ApplicationUiSettingsForm():
class _ApplicationUiSettingsForm(_BaseVcsSettingsForm):
web_push_ssl = v.StringBoolean(if_missing=False)
paths_root_path = All(
v.ValidPath(),
v.UnicodeString(strip=True, min=1, not_empty=True)
)
extensions_hgsubversion = v.StringBoolean(if_missing=False)
extensions_hggit = v.StringBoolean(if_missing=False)
new_svn_branch = v.ValidSvnPattern(section='vcs_svn_branch')
new_svn_tag = v.ValidSvnPattern(section='vcs_svn_tag')
return _ApplicationUiSettingsForm
def RepoVcsSettingsForm(repo_name):
class _RepoVcsSettingsForm(_BaseVcsSettingsForm):
inherit_global_settings = v.StringBoolean(if_missing=False)
new_svn_branch = v.ValidSvnPattern(
section='vcs_svn_branch', repo_name=repo_name)
new_svn_tag = v.ValidSvnPattern(
section='vcs_svn_tag', repo_name=repo_name)
return _RepoVcsSettingsForm
def LabsSettingsForm():
class _LabSettingsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
return _LabSettingsForm
def ApplicationPermissionsForm(register_choices, extern_activate_choices):
class _DefaultPermissionsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
anonymous = v.StringBoolean(if_missing=False)
default_register = v.OneOf(register_choices)
default_register_message = v.UnicodeString()
default_extern_activate = v.OneOf(extern_activate_choices)
return _DefaultPermissionsForm
def ObjectPermissionsForm(repo_perms_choices, group_perms_choices,
user_group_perms_choices):
class _ObjectPermissionsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
overwrite_default_repo = v.StringBoolean(if_missing=False)
overwrite_default_group = v.StringBoolean(if_missing=False)
overwrite_default_user_group = v.StringBoolean(if_missing=False)
default_repo_perm = v.OneOf(repo_perms_choices)
default_group_perm = v.OneOf(group_perms_choices)
default_user_group_perm = v.OneOf(user_group_perms_choices)
return _ObjectPermissionsForm
def UserPermissionsForm(create_choices, create_on_write_choices,
repo_group_create_choices, user_group_create_choices,
fork_choices, inherit_default_permissions_choices):
class _DefaultPermissionsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
anonymous = v.StringBoolean(if_missing=False)
default_repo_create = v.OneOf(create_choices)
default_repo_create_on_write = v.OneOf(create_on_write_choices)
default_user_group_create = v.OneOf(user_group_create_choices)
default_repo_group_create = v.OneOf(repo_group_create_choices)
default_fork_create = v.OneOf(fork_choices)
default_inherit_default_permissions = v.OneOf(inherit_default_permissions_choices)
return _DefaultPermissionsForm
def UserIndividualPermissionsForm():
class _DefaultPermissionsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
inherit_default_permissions = v.StringBoolean(if_missing=False)
return _DefaultPermissionsForm
def DefaultsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys()):
class _DefaultsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
default_repo_type = v.OneOf(supported_backends)
default_repo_private = v.StringBoolean(if_missing=False)
default_repo_enable_statistics = v.StringBoolean(if_missing=False)
default_repo_enable_downloads = v.StringBoolean(if_missing=False)
default_repo_enable_locking = v.StringBoolean(if_missing=False)
return _DefaultsForm
def AuthSettingsForm():
class _AuthSettingsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
auth_plugins = All(v.ValidAuthPlugins(),
v.UniqueListFromString()(not_empty=True))
return _AuthSettingsForm
def UserExtraEmailForm():
class _UserExtraEmailForm(formencode.Schema):
email = All(v.UniqSystemEmail(), v.Email(not_empty=True))
return _UserExtraEmailForm
def UserExtraIpForm():
class _UserExtraIpForm(formencode.Schema):
ip = v.ValidIp()(not_empty=True)
return _UserExtraIpForm
dan
reviewers: store reviewer reasons to database, fixes #4238
r873
project: added all source files and assets
r1 def PullRequestForm(repo_id):
dan
reviewers: store reviewer reasons to database, fixes #4238
r873 class ReviewerForm(formencode.Schema):
user_id = v.Int(not_empty=True)
reasons = All()
project: added all source files and assets
r1 class _PullRequestForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
user = v.UnicodeString(strip=True, required=True)
source_repo = v.UnicodeString(strip=True, required=True)
source_ref = v.UnicodeString(strip=True, required=True)
target_repo = v.UnicodeString(strip=True, required=True)
target_ref = v.UnicodeString(strip=True, required=True)
revisions = All(#v.NotReviewedRevisions(repo_id)(),
v.UniqueList()(not_empty=True))
dan
reviewers: store reviewer reasons to database, fixes #4238
r873 review_members = formencode.ForEach(ReviewerForm())
project: added all source files and assets
r1 pullrequest_title = v.UnicodeString(strip=True, required=True)
pullrequest_desc = v.UnicodeString(strip=True, required=False)
return _PullRequestForm
def IssueTrackerPatternsForm():
class _IssueTrackerPatternsForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = False
chained_validators = [v.ValidPattern()]
return _IssueTrackerPatternsForm