##// END OF EJS Templates
svn-support: generate http downgrade only if we force_https in config.
marcink -
r1218:96294b6a default
parent child Browse files
Show More
@@ -1,137 +1,138 b''
1 .. _svn-http:
1 .. _svn-http:
2
2
3 |svn| With Write Over HTTP
3 |svn| With Write Over HTTP
4 ^^^^^^^^^^^^^^^^^^^^^^^^^^
4 ^^^^^^^^^^^^^^^^^^^^^^^^^^
5
5
6 To use |svn| with read/write support over the |svn| HTTP protocol, you have to
6 To use |svn| with read/write support over the |svn| HTTP protocol, you have to
7 configure the HTTP |svn| backend.
7 configure the HTTP |svn| backend.
8
8
9 Prerequisites
9 Prerequisites
10 =============
10 =============
11
11
12 - Enable HTTP support inside the admin VCS settings on your |RCE| instance
12 - Enable HTTP support inside the admin VCS settings on your |RCE| instance
13 - You need to install the following tools on the machine that is running an
13 - You need to install the following tools on the machine that is running an
14 instance of |RCE|:
14 instance of |RCE|:
15 ``Apache HTTP Server`` and ``mod_dav_svn``.
15 ``Apache HTTP Server`` and ``mod_dav_svn``.
16
16
17
17
18 Using Ubuntu 14.04 Distribution as an example execute the following:
18 Using Ubuntu 14.04 Distribution as an example execute the following:
19
19
20 .. code-block:: bash
20 .. code-block:: bash
21
21
22 $ sudo apt-get install apache2 libapache2-mod-svn
22 $ sudo apt-get install apache2 libapache2-mod-svn
23
23
24 Once installed you need to enable ``dav_svn``:
24 Once installed you need to enable ``dav_svn``:
25
25
26 .. code-block:: bash
26 .. code-block:: bash
27
27
28 $ sudo a2enmod dav_svn
28 $ sudo a2enmod dav_svn
29 $ sudo a2enmod headers
29 $ sudo a2enmod headers
30 $ sudo a2enmod authn_anon
30
31
31
32
32 Configuring Apache Setup
33 Configuring Apache Setup
33 ========================
34 ========================
34
35
35 .. tip::
36 .. tip::
36
37
37 It is recommended to run Apache on a port other than 80, due to possible
38 It is recommended to run Apache on a port other than 80, due to possible
38 conflicts with other HTTP servers like nginx. To do this, set the
39 conflicts with other HTTP servers like nginx. To do this, set the
39 ``Listen`` parameter in the ``/etc/apache2/ports.conf`` file, for example
40 ``Listen`` parameter in the ``/etc/apache2/ports.conf`` file, for example
40 ``Listen 8090``.
41 ``Listen 8090``.
41
42
42
43
43 .. warning::
44 .. warning::
44
45
45 Make sure your Apache instance which runs the mod_dav_svn module is
46 Make sure your Apache instance which runs the mod_dav_svn module is
46 only accessible by |RCE|. Otherwise everyone is able to browse
47 only accessible by |RCE|. Otherwise everyone is able to browse
47 the repositories or run subversion operations (checkout/commit/etc.).
48 the repositories or run subversion operations (checkout/commit/etc.).
48
49
49 It is also recommended to run apache as the same user as |RCE|, otherwise
50 It is also recommended to run apache as the same user as |RCE|, otherwise
50 permission issues could occur. To do this edit the ``/etc/apache2/envvars``
51 permission issues could occur. To do this edit the ``/etc/apache2/envvars``
51
52
52 .. code-block:: apache
53 .. code-block:: apache
53
54
54 export APACHE_RUN_USER=rhodecode
55 export APACHE_RUN_USER=rhodecode
55 export APACHE_RUN_GROUP=rhodecode
56 export APACHE_RUN_GROUP=rhodecode
56
57
57 1. To configure Apache, create and edit a virtual hosts file, for example
58 1. To configure Apache, create and edit a virtual hosts file, for example
58 :file:`/etc/apache2/sites-available/default.conf`. Below is an example
59 :file:`/etc/apache2/sites-enabled/default.conf`. Below is an example
59 how to use one with auto-generated config ```mod_dav_svn.conf```
60 how to use one with auto-generated config ```mod_dav_svn.conf```
60 from configured |RCE| instance.
61 from configured |RCE| instance.
61
62
62 .. code-block:: apache
63 .. code-block:: apache
63
64
64 <VirtualHost *:8090>
65 <VirtualHost *:8090>
65 ServerAdmin rhodecode-admin@localhost
66 ServerAdmin rhodecode-admin@localhost
66 DocumentRoot /var/www/html
67 DocumentRoot /var/www/html
67 ErrorLog ${'${APACHE_LOG_DIR}'}/error.log
68 ErrorLog ${'${APACHE_LOG_DIR}'}/error.log
68 CustomLog ${'${APACHE_LOG_DIR}'}/access.log combined
69 CustomLog ${'${APACHE_LOG_DIR}'}/access.log combined
69 Include /home/user/.rccontrol/enterprise-1/mod_dav_svn.conf
70 Include /home/user/.rccontrol/enterprise-1/mod_dav_svn.conf
70 </VirtualHost>
71 </VirtualHost>
71
72
72
73
73 2. Go to the :menuselection:`Admin --> Settings --> VCS` page, and
74 2. Go to the :menuselection:`Admin --> Settings --> VCS` page, and
74 enable :guilabel:`Proxy Subversion HTTP requests`, and specify the
75 enable :guilabel:`Proxy Subversion HTTP requests`, and specify the
75 :guilabel:`Subversion HTTP Server URL`.
76 :guilabel:`Subversion HTTP Server URL`.
76
77
77 3. Open the |RCE| configuration file,
78 3. Open the |RCE| configuration file,
78 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
79 :file:`/home/{user}/.rccontrol/{instance-id}/rhodecode.ini`
79
80
80 4. Add the following configuration option in the ``[app:main]``
81 4. Add the following configuration option in the ``[app:main]``
81 section if you don't have it yet.
82 section if you don't have it yet.
82
83
83 This enables mapping of the created |RCE| repo groups into special
84 This enables mapping of the created |RCE| repo groups into special
84 |svn| paths. Each time a new repository group is created, the system will
85 |svn| paths. Each time a new repository group is created, the system will
85 update the template file and create new mapping. Apache web server needs to
86 update the template file and create new mapping. Apache web server needs to
86 be reloaded to pick up the changes on this file.
87 be reloaded to pick up the changes on this file.
87 To do this, simply configure `svn.proxy.reload_cmd` inside the .ini file.
88 To do this, simply configure `svn.proxy.reload_cmd` inside the .ini file.
88 Example configuration:
89 Example configuration:
89
90
90
91
91 .. code-block:: ini
92 .. code-block:: ini
92
93
93 ############################################################
94 ############################################################
94 ### Subversion proxy support (mod_dav_svn) ###
95 ### Subversion proxy support (mod_dav_svn) ###
95 ### Maps RhodeCode repo groups into SVN paths for Apache ###
96 ### Maps RhodeCode repo groups into SVN paths for Apache ###
96 ############################################################
97 ############################################################
97 ## Enable or disable the config file generation.
98 ## Enable or disable the config file generation.
98 svn.proxy.generate_config = true
99 svn.proxy.generate_config = true
99 ## Generate config file with `SVNListParentPath` set to `On`.
100 ## Generate config file with `SVNListParentPath` set to `On`.
100 svn.proxy.list_parent_path = true
101 svn.proxy.list_parent_path = true
101 ## Set location and file name of generated config file.
102 ## Set location and file name of generated config file.
102 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
103 svn.proxy.config_file_path = %(here)s/mod_dav_svn.conf
103 ## Used as a prefix to the <Location> block in the generated config file.
104 ## Used as a prefix to the <Location> block in the generated config file.
104 ## In most cases it should be set to `/`.
105 ## In most cases it should be set to `/`.
105 svn.proxy.location_root = /
106 svn.proxy.location_root = /
106 ## Command to reload the mod dav svn configuration on change.
107 ## Command to reload the mod dav svn configuration on change.
107 ## Example: `/etc/init.d/apache2 reload`
108 ## Example: `/etc/init.d/apache2 reload`
108 svn.proxy.reload_cmd = /etc/init.d/apache2 reload
109 svn.proxy.reload_cmd = /etc/init.d/apache2 reload
109 ## If the timeout expires before the reload command finishes, the command will
110 ## If the timeout expires before the reload command finishes, the command will
110 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
111 ## be killed. Setting it to zero means no timeout. Defaults to 10 seconds.
111 #svn.proxy.reload_timeout = 10
112 #svn.proxy.reload_timeout = 10
112
113
113
114
114 This would create a special template file called ```mod_dav_svn.conf```. We
115 This would create a special template file called ```mod_dav_svn.conf```. We
115 used that file path in the apache config above inside the Include statement.
116 used that file path in the apache config above inside the Include statement.
116 It's also possible to generate the config from the
117 It's also possible to generate the config from the
117 :menuselection:`Admin --> Settings --> VCS` page.
118 :menuselection:`Admin --> Settings --> VCS` page.
118
119
119
120
120 Using |svn|
121 Using |svn|
121 ===========
122 ===========
122
123
123 Once |svn| has been enabled on your instance, you can use it with the
124 Once |svn| has been enabled on your instance, you can use it with the
124 following examples. For more |svn| information, see the `Subversion Red Book`_
125 following examples. For more |svn| information, see the `Subversion Red Book`_
125
126
126 .. code-block:: bash
127 .. code-block:: bash
127
128
128 # To clone a repository
129 # To clone a repository
129 svn checkout http://my-svn-server.example.com/my-svn-repo
130 svn checkout http://my-svn-server.example.com/my-svn-repo
130
131
131 # svn commit
132 # svn commit
132 svn commit
133 svn commit
133
134
134
135
135 .. _Subversion Red Book: http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.ref.svn
136 .. _Subversion Red Book: http://svnbook.red-bean.com/en/1.7/svn-book.html#svn.ref.svn
136
137
137 .. _Ask Ubuntu: http://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue No newline at end of file
138 .. _Ask Ubuntu: http://askubuntu.com/questions/162391/how-do-i-fix-my-locale-issue
@@ -1,79 +1,83 b''
1 # Auto generated configuration for use with the Apache mod_dav_svn module.
1 # Auto generated configuration for use with the Apache mod_dav_svn module.
2 #
2 #
3 # WARNING: Make sure your Apache instance which runs the mod_dav_svn module is
3 # WARNING: Make sure your Apache instance which runs the mod_dav_svn module is
4 # only accessible by RhodeCode. Otherwise everyone is able to browse
4 # only accessible by RhodeCode. Otherwise everyone is able to browse
5 # the repositories or run subversion operations (checkout/commit/etc.).
5 # the repositories or run subversion operations (checkout/commit/etc.).
6 #
6 #
7 # The mod_dav_svn module does not support subversion repositories which are
7 # The mod_dav_svn module does not support subversion repositories which are
8 # organized in subfolders. To support the repository groups of RhodeCode it is
8 # organized in subfolders. To support the repository groups of RhodeCode it is
9 # required to provide a <Location> block for each group pointing to the
9 # required to provide a <Location> block for each group pointing to the
10 # repository group sub folder. To ease the configuration RhodeCode auto
10 # repository group sub folder. To ease the configuration RhodeCode auto
11 # generates this file whenever a repository group is created/changed/deleted.
11 # generates this file whenever a repository group is created/changed/deleted.
12 # Auto generation can be configured in the ini file. Settings are prefixed with
12 # Auto generation can be configured in the ini file. Settings are prefixed with
13 # ``svn.proxy``.
13 # ``svn.proxy``.
14 #
14 #
15 # To include this configuration into your apache config you can use the
15 # To include this configuration into your apache config you can use the
16 # `Include` directive. See the following example snippet of a virtual host how
16 # `Include` directive. See the following example snippet of a virtual host how
17 # to include this configuration file.
17 # to include this configuration file.
18 #
18 #
19 # <VirtualHost *:8080>
19 # <VirtualHost *:8090>
20 # ServerAdmin webmaster@localhost
20 # ServerAdmin webmaster@localhost
21 # DocumentRoot /var/www/html
21 # DocumentRoot /var/www/html
22 # ErrorLog ${'${APACHE_LOG_DIR}'}/error.log
22 # ErrorLog ${'${APACHE_LOG_DIR}'}/error.log
23 # CustomLog ${'${APACHE_LOG_DIR}'}/access.log combined
23 # CustomLog ${'${APACHE_LOG_DIR}'}/access.log combined
24 # Include /path/to/generated/mod_dav_svn.conf
24 # Include /path/to/generated/mod_dav_svn.conf
25 # </VirtualHost>
25 # </VirtualHost>
26 #
26 #
27 # Depending on the apache configuration you may encounter the following error if
27 # Depending on the apache configuration you may encounter the following error if
28 # you are using speecial characters in your repository or repository group
28 # you are using speecial characters in your repository or repository group
29 # names.
29 # names.
30 #
30 #
31 # ``Error converting entry in directory '/path/to/repo' to UTF-8``
31 # ``Error converting entry in directory '/path/to/repo' to UTF-8``
32 #
32 #
33 # In this case you have to change the LANG environment variable in the apache
33 # In this case you have to change the LANG environment variable in the apache
34 # configuration. This setting is typically located at ``/etc/apache2/envvars``.
34 # configuration. This setting is typically located at ``/etc/apache2/envvars``.
35 # You have to change it to an UTF-8 value like ``export LANG="en_US.UTF-8"``.
35 # You have to change it to an UTF-8 value like ``export LANG="en_US.UTF-8"``.
36 # After changing this a stop and start of Apache is required (using restart
36 # After changing this a stop and start of Apache is required (using restart
37 # doesn't work).
37 # doesn't work).
38
38
39 # fix https -> http downgrade with DAV. It requires an header downgrade for
39 # fix https -> http downgrade with DAV. It requires an header downgrade for
40 # https -> http reverse proxy to work properly
40 # https -> http reverse proxy to work properly
41 % if use_https:
41 RequestHeader edit Destination ^https: http: early
42 RequestHeader edit Destination ^https: http: early
43 % else:
44 #RequestHeader edit Destination ^https: http: early
45 % endif
42
46
43 <Location "${location_root|n}">
47 <Location "${location_root|n}">
44 # The mod_dav_svn module takes the username from the apache request object.
48 # The mod_dav_svn module takes the username from the apache request object.
45 # Without authorization this will be empty and no username is logged for the
49 # Without authorization this will be empty and no username is logged for the
46 # transactions. This will result in "(no author)" for each revision. The
50 # transactions. This will result in "(no author)" for each revision. The
47 # following directives implement a fake authentication that allows every
51 # following directives implement a fake authentication that allows every
48 # username/password combination.
52 # username/password combination.
49 AuthType Basic
53 AuthType Basic
50 AuthName "${rhodecode_realm|n}"
54 AuthName "${rhodecode_realm|n}"
51 AuthBasicProvider anon
55 AuthBasicProvider anon
52 Anonymous *
56 Anonymous *
53 Require valid-user
57 Require valid-user
54
58
55 DAV svn
59 DAV svn
56 SVNParentPath "${parent_path_root|n}"
60 SVNParentPath "${parent_path_root|n}"
57 SVNListParentPath ${"On" if svn_list_parent_path else "Off"|n}
61 SVNListParentPath ${"On" if svn_list_parent_path else "Off"|n}
58
62
59 Allow from all
63 Allow from all
60 Order allow,deny
64 Order allow,deny
61 </Location>
65 </Location>
62
66
63 % for location, parent_path in repo_group_paths:
67 % for location, parent_path in repo_group_paths:
64
68
65 <Location "${location|n}">
69 <Location "${location|n}">
66 AuthType Basic
70 AuthType Basic
67 AuthName "${rhodecode_realm|n}"
71 AuthName "${rhodecode_realm|n}"
68 AuthBasicProvider anon
72 AuthBasicProvider anon
69 Anonymous *
73 Anonymous *
70 Require valid-user
74 Require valid-user
71
75
72 DAV svn
76 DAV svn
73 SVNParentPath "${parent_path|n}"
77 SVNParentPath "${parent_path|n}"
74 SVNListParentPath ${"On" if svn_list_parent_path else "Off"|n}
78 SVNListParentPath ${"On" if svn_list_parent_path else "Off"|n}
75
79
76 Allow from all
80 Allow from all
77 Order allow,deny
81 Order allow,deny
78 </Location>
82 </Location>
79 % endfor
83 % endfor
@@ -1,97 +1,107 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21
21
22 import mock
22 import mock
23 import pytest
23 import pytest
24 import re
24 import re
25
25
26 from pyramid import testing
26 from pyramid import testing
27
27
28 from rhodecode.svn_support import utils
28 from rhodecode.svn_support import utils
29
29
30
30
31 class TestModDavSvnConfig(object):
31 class TestModDavSvnConfig(object):
32
32
33 @classmethod
33 @classmethod
34 def setup_class(cls):
34 def setup_class(cls):
35 # Make mako renderer available in tests.
35 # Make mako renderer available in tests.
36 config = testing.setUp()
36 config = testing.setUp()
37 config.include('pyramid_mako')
37 config.include('pyramid_mako')
38
38
39 cls.location_root = u'/location/root/ç¡Àâ'
39 cls.location_root = u'/location/root/ç¡Àâ'
40 cls.parent_path_root = u'/parent/path/ç¡Àâ'
40 cls.parent_path_root = u'/parent/path/ç¡Àâ'
41 cls.realm = u'Dummy Realm (Àâüç¡)'
41 cls.realm = u'Dummy Realm (Àâüç¡)'
42
42
43 @classmethod
43 @classmethod
44 def get_repo_group_mocks(cls, count=1):
44 def get_repo_group_mocks(cls, count=1):
45 repo_groups = []
45 repo_groups = []
46 for num in range(0, count):
46 for num in range(0, count):
47 full_path = u'/path/to/RepâGrâúp-°¡ {}'.format(num)
47 full_path = u'/path/to/RepâGrâúp-°¡ {}'.format(num)
48 repo_group_mock = mock.MagicMock()
48 repo_group_mock = mock.MagicMock()
49 repo_group_mock.full_path = full_path
49 repo_group_mock.full_path = full_path
50 repo_group_mock.full_path_splitted = full_path.split('/')
50 repo_group_mock.full_path_splitted = full_path.split('/')
51 repo_groups.append(repo_group_mock)
51 repo_groups.append(repo_group_mock)
52 return repo_groups
52 return repo_groups
53
53
54 def assert_root_location_directive(self, config):
54 def assert_root_location_directive(self, config):
55 pattern = u'<Location "{location}">'.format(
55 pattern = u'<Location "{location}">'.format(
56 location=self.location_root)
56 location=self.location_root)
57 assert len(re.findall(pattern, config)) == 1
57 assert len(re.findall(pattern, config)) == 1
58
58
59 def assert_group_location_directive(self, config, group_path):
59 def assert_group_location_directive(self, config, group_path):
60 pattern = u'<Location "{location}{group_path}">'.format(
60 pattern = u'<Location "{location}{group_path}">'.format(
61 location=self.location_root, group_path=group_path)
61 location=self.location_root, group_path=group_path)
62 assert len(re.findall(pattern, config)) == 1
62 assert len(re.findall(pattern, config)) == 1
63
63
64 def test_render_mod_dav_svn_config(self):
64 def test_render_mod_dav_svn_config(self):
65 repo_groups = self.get_repo_group_mocks(count=10)
65 repo_groups = self.get_repo_group_mocks(count=10)
66 generated_config = utils._render_mod_dav_svn_config(
66 generated_config = utils._render_mod_dav_svn_config(
67 parent_path_root=self.parent_path_root,
67 parent_path_root=self.parent_path_root,
68 list_parent_path=True,
68 list_parent_path=True,
69 location_root=self.location_root,
69 location_root=self.location_root,
70 repo_groups=repo_groups,
70 repo_groups=repo_groups,
71 realm=self.realm
71 realm=self.realm,
72 use_ssl=True
72 )
73 )
73 # Assert that one location directive exists for each repository group.
74 # Assert that one location directive exists for each repository group.
74 for group in repo_groups:
75 for group in repo_groups:
75 self.assert_group_location_directive(
76 self.assert_group_location_directive(
76 generated_config, group.full_path)
77 generated_config, group.full_path)
77
78
78 # Assert that the root location directive exists.
79 # Assert that the root location directive exists.
79 self.assert_root_location_directive(generated_config)
80 self.assert_root_location_directive(generated_config)
80
81
81 @pytest.mark.parametrize('list_parent_path', [True, False])
82 @pytest.mark.parametrize('list_parent_path', [True, False])
82 def test_list_parent_path(self, list_parent_path):
83 @pytest.mark.parametrize('use_ssl', [True, False])
84 def test_list_parent_path(self, list_parent_path, use_ssl):
83 generated_config = utils._render_mod_dav_svn_config(
85 generated_config = utils._render_mod_dav_svn_config(
84 parent_path_root=self.parent_path_root,
86 parent_path_root=self.parent_path_root,
85 list_parent_path=list_parent_path,
87 list_parent_path=list_parent_path,
86 location_root=self.location_root,
88 location_root=self.location_root,
87 repo_groups=self.get_repo_group_mocks(count=10),
89 repo_groups=self.get_repo_group_mocks(count=10),
88 realm=self.realm
90 realm=self.realm,
91 use_ssl=use_ssl
89 )
92 )
90
93
91 # Assert that correct configuration directive is present.
94 # Assert that correct configuration directive is present.
92 if list_parent_path:
95 if list_parent_path:
93 assert not re.search('SVNListParentPath\s+Off', generated_config)
96 assert not re.search('SVNListParentPath\s+Off', generated_config)
94 assert re.search('SVNListParentPath\s+On', generated_config)
97 assert re.search('SVNListParentPath\s+On', generated_config)
95 else:
98 else:
96 assert re.search('SVNListParentPath\s+Off', generated_config)
99 assert re.search('SVNListParentPath\s+Off', generated_config)
97 assert not re.search('SVNListParentPath\s+On', generated_config)
100 assert not re.search('SVNListParentPath\s+On', generated_config)
101
102 if use_ssl:
103 assert 'RequestHeader edit Destination ^https: http: early' \
104 in generated_config
105 else:
106 assert '#RequestHeader edit Destination ^https: http: early' \
107 in generated_config
@@ -1,87 +1,93 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import codecs
21 import codecs
22 import logging
22 import logging
23 import os
23 import os
24 from pyramid.renderers import render
24 from pyramid.renderers import render
25
25
26 from rhodecode.events import trigger
26 from rhodecode.events import trigger
27 from rhodecode.lib.utils import get_rhodecode_realm, get_rhodecode_base_path
27 from rhodecode.lib.utils import get_rhodecode_realm, get_rhodecode_base_path
28 from rhodecode.lib.utils2 import str2bool
28 from rhodecode.model.db import RepoGroup
29 from rhodecode.model.db import RepoGroup
29
30
30 from . import config_keys
31 from . import config_keys
31 from .events import ModDavSvnConfigChange
32 from .events import ModDavSvnConfigChange
32
33
33
34
34 log = logging.getLogger(__name__)
35 log = logging.getLogger(__name__)
35
36
36
37
37 def generate_mod_dav_svn_config(registry):
38 def generate_mod_dav_svn_config(registry):
38 """
39 """
39 Generate the configuration file for use with subversion's mod_dav_svn
40 Generate the configuration file for use with subversion's mod_dav_svn
40 module. The configuration has to contain a <Location> block for each
41 module. The configuration has to contain a <Location> block for each
41 available repository group because the mod_dav_svn module does not support
42 available repository group because the mod_dav_svn module does not support
42 repositories organized in sub folders.
43 repositories organized in sub folders.
43 """
44 """
44 settings = registry.settings
45 settings = registry.settings
46 use_ssl = str2bool(registry.settings['force_https'])
47
45 config = _render_mod_dav_svn_config(
48 config = _render_mod_dav_svn_config(
49 use_ssl=use_ssl,
46 parent_path_root=get_rhodecode_base_path(),
50 parent_path_root=get_rhodecode_base_path(),
47 list_parent_path=settings[config_keys.list_parent_path],
51 list_parent_path=settings[config_keys.list_parent_path],
48 location_root=settings[config_keys.location_root],
52 location_root=settings[config_keys.location_root],
49 repo_groups=RepoGroup.get_all_repo_groups(),
53 repo_groups=RepoGroup.get_all_repo_groups(),
50 realm=get_rhodecode_realm())
54 realm=get_rhodecode_realm())
51 _write_mod_dav_svn_config(config, settings[config_keys.config_file_path])
55 _write_mod_dav_svn_config(config, settings[config_keys.config_file_path])
52
56
53 # Trigger an event on mod dav svn configuration change.
57 # Trigger an event on mod dav svn configuration change.
54 trigger(ModDavSvnConfigChange(), registry)
58 trigger(ModDavSvnConfigChange(), registry)
55
59
56
60
57 def _render_mod_dav_svn_config(
61 def _render_mod_dav_svn_config(
58 parent_path_root, list_parent_path, location_root, repo_groups, realm):
62 parent_path_root, list_parent_path, location_root, repo_groups, realm,
63 use_ssl):
59 """
64 """
60 Render mod_dav_svn configuration to string.
65 Render mod_dav_svn configuration to string.
61 """
66 """
62 repo_group_paths = []
67 repo_group_paths = []
63 for repo_group in repo_groups:
68 for repo_group in repo_groups:
64 group_path = repo_group.full_path_splitted
69 group_path = repo_group.full_path_splitted
65 location = os.path.join(location_root, *group_path)
70 location = os.path.join(location_root, *group_path)
66 parent_path = os.path.join(parent_path_root, *group_path)
71 parent_path = os.path.join(parent_path_root, *group_path)
67 repo_group_paths.append((location, parent_path))
72 repo_group_paths.append((location, parent_path))
68
73
69 context = {
74 context = {
70 'location_root': location_root,
75 'location_root': location_root,
71 'parent_path_root': parent_path_root,
76 'parent_path_root': parent_path_root,
72 'repo_group_paths': repo_group_paths,
77 'repo_group_paths': repo_group_paths,
73 'svn_list_parent_path': list_parent_path,
78 'svn_list_parent_path': list_parent_path,
74 'rhodecode_realm': realm,
79 'rhodecode_realm': realm,
80 'use_https': use_ssl
75 }
81 }
76
82
77 # Render the configuration template to string.
83 # Render the configuration template to string.
78 template = 'rhodecode:svn_support/templates/mod-dav-svn.conf.mako'
84 template = 'rhodecode:svn_support/templates/mod-dav-svn.conf.mako'
79 return render(template, context)
85 return render(template, context)
80
86
81
87
82 def _write_mod_dav_svn_config(config, filepath):
88 def _write_mod_dav_svn_config(config, filepath):
83 """
89 """
84 Write mod_dav_svn config to file.
90 Write mod_dav_svn config to file.
85 """
91 """
86 with codecs.open(filepath, 'w', encoding='utf-8') as f:
92 with codecs.open(filepath, 'w', encoding='utf-8') as f:
87 f.write(config)
93 f.write(config)
@@ -1,275 +1,275 b''
1 ## snippet for displaying vcs settings
1 ## snippet for displaying vcs settings
2 ## usage:
2 ## usage:
3 ## <%namespace name="vcss" file="/base/vcssettings.html"/>
3 ## <%namespace name="vcss" file="/base/vcssettings.html"/>
4 ## ${vcss.vcs_settings_fields()}
4 ## ${vcss.vcs_settings_fields()}
5
5
6 <%def name="vcs_settings_fields(suffix='', svn_branch_patterns=None, svn_tag_patterns=None, repo_type=None, display_globals=False, allow_repo_location_change=False, **kwargs)">
6 <%def name="vcs_settings_fields(suffix='', svn_branch_patterns=None, svn_tag_patterns=None, repo_type=None, display_globals=False, allow_repo_location_change=False, **kwargs)">
7 % if display_globals:
7 % if display_globals:
8 <div class="panel panel-default">
8 <div class="panel panel-default">
9 <div class="panel-heading" id="general">
9 <div class="panel-heading" id="general">
10 <h3 class="panel-title">${_('General')}</h3>
10 <h3 class="panel-title">${_('General')}</h3>
11 </div>
11 </div>
12 <div class="panel-body">
12 <div class="panel-body">
13 <div class="field">
13 <div class="field">
14 <div class="checkbox">
14 <div class="checkbox">
15 ${h.checkbox('web_push_ssl' + suffix, 'True')}
15 ${h.checkbox('web_push_ssl' + suffix, 'True')}
16 <label for="web_push_ssl${suffix}">${_('Require SSL for vcs operations')}</label>
16 <label for="web_push_ssl${suffix}">${_('Require SSL for vcs operations')}</label>
17 </div>
17 </div>
18 <div class="label">
18 <div class="label">
19 <span class="help-block">${_('Activate to set RhodeCode to require SSL for pushing or pulling. If SSL certificate is missing it will return a HTTP Error 406: Not Acceptable.')}</span>
19 <span class="help-block">${_('Activate to set RhodeCode to require SSL for pushing or pulling. If SSL certificate is missing it will return a HTTP Error 406: Not Acceptable.')}</span>
20 </div>
20 </div>
21 </div>
21 </div>
22 </div>
22 </div>
23 </div>
23 </div>
24 % endif
24 % endif
25
25
26 % if display_globals:
26 % if display_globals:
27 <div class="panel panel-default">
27 <div class="panel panel-default">
28 <div class="panel-heading">
28 <div class="panel-heading">
29 <h3 class="panel-title">${_('Main Storage Location')}</h3>
29 <h3 class="panel-title">${_('Main Storage Location')}</h3>
30 </div>
30 </div>
31 <div class="panel-body">
31 <div class="panel-body">
32 <div class="field">
32 <div class="field">
33 <div class="inputx locked_input">
33 <div class="inputx locked_input">
34 %if allow_repo_location_change:
34 %if allow_repo_location_change:
35 ${h.text('paths_root_path',size=59,readonly="readonly", class_="disabled")}
35 ${h.text('paths_root_path',size=59,readonly="readonly", class_="disabled")}
36 <span id="path_unlock" class="tooltip"
36 <span id="path_unlock" class="tooltip"
37 title="${h.tooltip(_('Click to unlock. You must restart RhodeCode in order to make this setting take effect.'))}">
37 title="${h.tooltip(_('Click to unlock. You must restart RhodeCode in order to make this setting take effect.'))}">
38 <div class="btn btn-default lock_input_button"><i id="path_unlock_icon" class="icon-lock"></i></div>
38 <div class="btn btn-default lock_input_button"><i id="path_unlock_icon" class="icon-lock"></i></div>
39 </span>
39 </span>
40 %else:
40 %else:
41 ${_('Repository location change is disabled. You can enable this by changing the `allow_repo_location_change` inside .ini file.')}
41 ${_('Repository location change is disabled. You can enable this by changing the `allow_repo_location_change` inside .ini file.')}
42 ## form still requires this but we cannot internally change it anyway
42 ## form still requires this but we cannot internally change it anyway
43 ${h.hidden('paths_root_path',size=30,readonly="readonly", class_="disabled")}
43 ${h.hidden('paths_root_path',size=30,readonly="readonly", class_="disabled")}
44 %endif
44 %endif
45 </div>
45 </div>
46 </div>
46 </div>
47 <div class="label">
47 <div class="label">
48 <span class="help-block">${_('Filesystem location where repositories should be stored. After changing this value a restart and rescan of the repository folder are required.')}</span>
48 <span class="help-block">${_('Filesystem location where repositories should be stored. After changing this value a restart and rescan of the repository folder are required.')}</span>
49 </div>
49 </div>
50 </div>
50 </div>
51 </div>
51 </div>
52 % endif
52 % endif
53
53
54 % if display_globals or repo_type in ['git', 'hg']:
54 % if display_globals or repo_type in ['git', 'hg']:
55 <div class="panel panel-default">
55 <div class="panel panel-default">
56 <div class="panel-heading" id="general">
56 <div class="panel-heading" id="general">
57 <h3 class="panel-title">${_('Internal Hooks')}</h3>
57 <h3 class="panel-title">${_('Internal Hooks')}</h3>
58 </div>
58 </div>
59 <div class="panel-body">
59 <div class="panel-body">
60 <div class="field">
60 <div class="field">
61 <div class="checkbox">
61 <div class="checkbox">
62 ${h.checkbox('hooks_changegroup_repo_size' + suffix, 'True', **kwargs)}
62 ${h.checkbox('hooks_changegroup_repo_size' + suffix, 'True', **kwargs)}
63 <label for="hooks_changegroup_repo_size${suffix}">${_('Show repository size after push')}</label>
63 <label for="hooks_changegroup_repo_size${suffix}">${_('Show repository size after push')}</label>
64 </div>
64 </div>
65
65
66 <div class="label">
66 <div class="label">
67 <span class="help-block">${_('Trigger a hook that calculates repository size after each push.')}</span>
67 <span class="help-block">${_('Trigger a hook that calculates repository size after each push.')}</span>
68 </div>
68 </div>
69 <div class="checkbox">
69 <div class="checkbox">
70 ${h.checkbox('hooks_changegroup_push_logger' + suffix, 'True', **kwargs)}
70 ${h.checkbox('hooks_changegroup_push_logger' + suffix, 'True', **kwargs)}
71 <label for="hooks_changegroup_push_logger${suffix}">${_('Execute pre/post push hooks')}</label>
71 <label for="hooks_changegroup_push_logger${suffix}">${_('Execute pre/post push hooks')}</label>
72 </div>
72 </div>
73 <div class="label">
73 <div class="label">
74 <span class="help-block">${_('Execute Built in pre/post push hooks. This also executes rcextensions hooks.')}</span>
74 <span class="help-block">${_('Execute Built in pre/post push hooks. This also executes rcextensions hooks.')}</span>
75 </div>
75 </div>
76 <div class="checkbox">
76 <div class="checkbox">
77 ${h.checkbox('hooks_outgoing_pull_logger' + suffix, 'True', **kwargs)}
77 ${h.checkbox('hooks_outgoing_pull_logger' + suffix, 'True', **kwargs)}
78 <label for="hooks_outgoing_pull_logger${suffix}">${_('Execute pre/post pull hooks')}</label>
78 <label for="hooks_outgoing_pull_logger${suffix}">${_('Execute pre/post pull hooks')}</label>
79 </div>
79 </div>
80 <div class="label">
80 <div class="label">
81 <span class="help-block">${_('Execute Built in pre/post pull hooks. This also executes rcextensions hooks.')}</span>
81 <span class="help-block">${_('Execute Built in pre/post pull hooks. This also executes rcextensions hooks.')}</span>
82 </div>
82 </div>
83 </div>
83 </div>
84 </div>
84 </div>
85 </div>
85 </div>
86 % endif
86 % endif
87
87
88 % if display_globals or repo_type in ['hg']:
88 % if display_globals or repo_type in ['hg']:
89 <div class="panel panel-default">
89 <div class="panel panel-default">
90 <div class="panel-heading">
90 <div class="panel-heading">
91 <h3 class="panel-title">${_('Mercurial Settings')}</h3>
91 <h3 class="panel-title">${_('Mercurial Settings')}</h3>
92 </div>
92 </div>
93 <div class="panel-body">
93 <div class="panel-body">
94 <div class="checkbox">
94 <div class="checkbox">
95 ${h.checkbox('extensions_largefiles' + suffix, 'True', **kwargs)}
95 ${h.checkbox('extensions_largefiles' + suffix, 'True', **kwargs)}
96 <label for="extensions_largefiles${suffix}">${_('Enable largefiles extension')}</label>
96 <label for="extensions_largefiles${suffix}">${_('Enable largefiles extension')}</label>
97 </div>
97 </div>
98 <div class="label">
98 <div class="label">
99 <span class="help-block">${_('Enable Largefiles extensions for all repositories.')}</span>
99 <span class="help-block">${_('Enable Largefiles extensions for all repositories.')}</span>
100 </div>
100 </div>
101 <div class="checkbox">
101 <div class="checkbox">
102 ${h.checkbox('phases_publish' + suffix, 'True', **kwargs)}
102 ${h.checkbox('phases_publish' + suffix, 'True', **kwargs)}
103 <label for="phases_publish${suffix}">${_('Set repositories as publishing') if display_globals else _('Set repository as publishing')}</label>
103 <label for="phases_publish${suffix}">${_('Set repositories as publishing') if display_globals else _('Set repository as publishing')}</label>
104 </div>
104 </div>
105 <div class="label">
105 <div class="label">
106 <span class="help-block">${_('When this is enabled all commits in the repository are seen as public commits by clients.')}</span>
106 <span class="help-block">${_('When this is enabled all commits in the repository are seen as public commits by clients.')}</span>
107 </div>
107 </div>
108 % if display_globals:
108 % if display_globals:
109 <div class="checkbox">
109 <div class="checkbox">
110 ${h.checkbox('extensions_hgsubversion' + suffix,'True')}
110 ${h.checkbox('extensions_hgsubversion' + suffix,'True')}
111 <label for="extensions_hgsubversion${suffix}">${_('Enable hgsubversion extension')}</label>
111 <label for="extensions_hgsubversion${suffix}">${_('Enable hgsubversion extension')}</label>
112 </div>
112 </div>
113 <div class="label">
113 <div class="label">
114 <span class="help-block">${_('Requires hgsubversion library to be installed. Allows cloning remote SVN repositories and migrates them to Mercurial type.')}</span>
114 <span class="help-block">${_('Requires hgsubversion library to be installed. Allows cloning remote SVN repositories and migrates them to Mercurial type.')}</span>
115 </div>
115 </div>
116 % endif
116 % endif
117 </div>
117 </div>
118 </div>
118 </div>
119 ## LABS for HG
119 ## LABS for HG
120 % if c.labs_active:
120 % if c.labs_active:
121 <div class="panel panel-danger">
121 <div class="panel panel-danger">
122 <div class="panel-heading">
122 <div class="panel-heading">
123 <h3 class="panel-title">${_('Mercurial Labs Settings')} (${_('These features are considered experimental and may not work as expected.')})</h3>
123 <h3 class="panel-title">${_('Mercurial Labs Settings')} (${_('These features are considered experimental and may not work as expected.')})</h3>
124 </div>
124 </div>
125 <div class="panel-body">
125 <div class="panel-body">
126
126
127 <div class="checkbox">
127 <div class="checkbox">
128 ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)}
128 ${h.checkbox('rhodecode_hg_use_rebase_for_merging' + suffix, 'True', **kwargs)}
129 <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
129 <label for="rhodecode_hg_use_rebase_for_merging${suffix}">${_('Use rebase as merge strategy')}</label>
130 </div>
130 </div>
131 <div class="label">
131 <div class="label">
132 <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
132 <span class="help-block">${_('Use rebase instead of creating a merge commit when merging via web interface.')}</span>
133 </div>
133 </div>
134
134
135 </div>
135 </div>
136 </div>
136 </div>
137 % endif
137 % endif
138
138
139 % endif
139 % endif
140
140
141 % if display_globals:
141 % if display_globals:
142 <div class="panel panel-default">
142 <div class="panel panel-default">
143 <div class="panel-heading">
143 <div class="panel-heading">
144 <h3 class="panel-title">${_('Global Subversion Settings')}</h3>
144 <h3 class="panel-title">${_('Global Subversion Settings')}</h3>
145 </div>
145 </div>
146 <div class="panel-body">
146 <div class="panel-body">
147 <div class="field">
147 <div class="field">
148 <div class="checkbox">
148 <div class="checkbox">
149 ${h.checkbox('vcs_svn_proxy_http_requests_enabled' + suffix, 'True', **kwargs)}
149 ${h.checkbox('vcs_svn_proxy_http_requests_enabled' + suffix, 'True', **kwargs)}
150 <label for="vcs_svn_proxy_http_requests_enabled${suffix}">${_('Proxy subversion HTTP requests')}</label>
150 <label for="vcs_svn_proxy_http_requests_enabled${suffix}">${_('Proxy subversion HTTP requests')}</label>
151 </div>
151 </div>
152 <div class="label">
152 <div class="label">
153 <span class="help-block">
153 <span class="help-block">
154 ${_('Subversion HTTP Support. Enables communication with SVN over HTTP protocol.')}
154 ${_('Subversion HTTP Support. Enables communication with SVN over HTTP protocol.')}
155 <a href="${h.url('enterprise_svn_setup')}" target="_blank">${_('SVN Protocol setup Documentation')}</a>.
155 <a href="${h.url('enterprise_svn_setup')}" target="_blank">${_('SVN Protocol setup Documentation')}</a>.
156 </span>
156 </span>
157 </div>
157 </div>
158 </div>
158 </div>
159 <div class="field">
159 <div class="field">
160 <div class="label">
160 <div class="label">
161 <label for="vcs_svn_proxy_http_server_url">${_('Subversion HTTP Server URL')}</label><br/>
161 <label for="vcs_svn_proxy_http_server_url">${_('Subversion HTTP Server URL')}</label><br/>
162 </div>
162 </div>
163 <div class="input">
163 <div class="input">
164 ${h.text('vcs_svn_proxy_http_server_url',size=59)}
164 ${h.text('vcs_svn_proxy_http_server_url',size=59)}
165 % if c.svn_proxy_generate_config:
166 <span class="buttons">
167 <button class="btn btn-primary" id="vcs_svn_generate_cfg">${_('Generate Apache Config')}</button>
168 </span>
169 % endif
165 </div>
170 </div>
166 </div>
171 </div>
167 % if c.svn_proxy_generate_config:
168 <div class="buttons">
169 <button class="btn btn-primary" id="vcs_svn_generate_cfg">${_('Generate Apache Config')}</button>
170 </div>
171 % endif
172 </div>
172 </div>
173 </div>
173 </div>
174 % endif
174 % endif
175
175
176 % if display_globals or repo_type in ['svn']:
176 % if display_globals or repo_type in ['svn']:
177 <div class="panel panel-default">
177 <div class="panel panel-default">
178 <div class="panel-heading">
178 <div class="panel-heading">
179 <h3 class="panel-title">${_('Subversion Settings')}</h3>
179 <h3 class="panel-title">${_('Subversion Settings')}</h3>
180 </div>
180 </div>
181 <div class="panel-body">
181 <div class="panel-body">
182 <div class="field">
182 <div class="field">
183 <div class="content" >
183 <div class="content" >
184 <label>${_('Repository patterns')}</label><br/>
184 <label>${_('Repository patterns')}</label><br/>
185 </div>
185 </div>
186 </div>
186 </div>
187 <div class="label">
187 <div class="label">
188 <span class="help-block">${_('Patterns for identifying SVN branches and tags. For recursive search, use "*". Eg.: "/branches/*"')}</span>
188 <span class="help-block">${_('Patterns for identifying SVN branches and tags. For recursive search, use "*". Eg.: "/branches/*"')}</span>
189 </div>
189 </div>
190
190
191 <div class="field branch_patterns">
191 <div class="field branch_patterns">
192 <div class="input" >
192 <div class="input" >
193 <label>${_('Branches')}:</label><br/>
193 <label>${_('Branches')}:</label><br/>
194 </div>
194 </div>
195 % if svn_branch_patterns:
195 % if svn_branch_patterns:
196 % for branch in svn_branch_patterns:
196 % for branch in svn_branch_patterns:
197 <div class="input adjacent" id="${'id%s' % branch.ui_id}">
197 <div class="input adjacent" id="${'id%s' % branch.ui_id}">
198 ${h.hidden('branch_ui_key' + suffix, branch.ui_key)}
198 ${h.hidden('branch_ui_key' + suffix, branch.ui_key)}
199 ${h.text('branch_value_%d' % branch.ui_id + suffix, branch.ui_value, size=59, readonly="readonly", class_='disabled')}
199 ${h.text('branch_value_%d' % branch.ui_id + suffix, branch.ui_value, size=59, readonly="readonly", class_='disabled')}
200 % if kwargs.get('disabled') != 'disabled':
200 % if kwargs.get('disabled') != 'disabled':
201 <span class="btn btn-x" onclick="ajaxDeletePattern(${branch.ui_id},'${'id%s' % branch.ui_id}')">
201 <span class="btn btn-x" onclick="ajaxDeletePattern(${branch.ui_id},'${'id%s' % branch.ui_id}')">
202 ${_('Delete')}
202 ${_('Delete')}
203 </span>
203 </span>
204 % endif
204 % endif
205 </div>
205 </div>
206 % endfor
206 % endfor
207 %endif
207 %endif
208 </div>
208 </div>
209 % if kwargs.get('disabled') != 'disabled':
209 % if kwargs.get('disabled') != 'disabled':
210 <div class="field branch_patterns">
210 <div class="field branch_patterns">
211 <div class="input" >
211 <div class="input" >
212 ${h.text('new_svn_branch',size=59,placeholder='New branch pattern')}
212 ${h.text('new_svn_branch',size=59,placeholder='New branch pattern')}
213 </div>
213 </div>
214 </div>
214 </div>
215 % endif
215 % endif
216 <div class="field tag_patterns">
216 <div class="field tag_patterns">
217 <div class="input" >
217 <div class="input" >
218 <label>${_('Tags')}:</label><br/>
218 <label>${_('Tags')}:</label><br/>
219 </div>
219 </div>
220 % if svn_tag_patterns:
220 % if svn_tag_patterns:
221 % for tag in svn_tag_patterns:
221 % for tag in svn_tag_patterns:
222 <div class="input" id="${'id%s' % tag.ui_id + suffix}">
222 <div class="input" id="${'id%s' % tag.ui_id + suffix}">
223 ${h.hidden('tag_ui_key' + suffix, tag.ui_key)}
223 ${h.hidden('tag_ui_key' + suffix, tag.ui_key)}
224 ${h.text('tag_ui_value_new_%d' % tag.ui_id + suffix, tag.ui_value, size=59, readonly="readonly", class_='disabled tag_input')}
224 ${h.text('tag_ui_value_new_%d' % tag.ui_id + suffix, tag.ui_value, size=59, readonly="readonly", class_='disabled tag_input')}
225 % if kwargs.get('disabled') != 'disabled':
225 % if kwargs.get('disabled') != 'disabled':
226 <span class="btn btn-x" onclick="ajaxDeletePattern(${tag.ui_id},'${'id%s' % tag.ui_id}')">
226 <span class="btn btn-x" onclick="ajaxDeletePattern(${tag.ui_id},'${'id%s' % tag.ui_id}')">
227 ${_('Delete')}
227 ${_('Delete')}
228 </span>
228 </span>
229 %endif
229 %endif
230 </div>
230 </div>
231 % endfor
231 % endfor
232 % endif
232 % endif
233 </div>
233 </div>
234 % if kwargs.get('disabled') != 'disabled':
234 % if kwargs.get('disabled') != 'disabled':
235 <div class="field tag_patterns">
235 <div class="field tag_patterns">
236 <div class="input" >
236 <div class="input" >
237 ${h.text('new_svn_tag' + suffix, size=59, placeholder='New tag pattern')}
237 ${h.text('new_svn_tag' + suffix, size=59, placeholder='New tag pattern')}
238 </div>
238 </div>
239 </div>
239 </div>
240 %endif
240 %endif
241 </div>
241 </div>
242 </div>
242 </div>
243 % else:
243 % else:
244 ${h.hidden('new_svn_branch' + suffix, '')}
244 ${h.hidden('new_svn_branch' + suffix, '')}
245 ${h.hidden('new_svn_tag' + suffix, '')}
245 ${h.hidden('new_svn_tag' + suffix, '')}
246 % endif
246 % endif
247
247
248
248
249
249
250
250
251 % if display_globals or repo_type in ['hg', 'git']:
251 % if display_globals or repo_type in ['hg', 'git']:
252 <div class="panel panel-default">
252 <div class="panel panel-default">
253 <div class="panel-heading">
253 <div class="panel-heading">
254 <h3 class="panel-title">${_('Pull Request Settings')}</h3>
254 <h3 class="panel-title">${_('Pull Request Settings')}</h3>
255 </div>
255 </div>
256 <div class="panel-body">
256 <div class="panel-body">
257 <div class="checkbox">
257 <div class="checkbox">
258 ${h.checkbox('rhodecode_pr_merge_enabled' + suffix, 'True', **kwargs)}
258 ${h.checkbox('rhodecode_pr_merge_enabled' + suffix, 'True', **kwargs)}
259 <label for="rhodecode_pr_merge_enabled${suffix}">${_('Enable server-side merge for pull requests')}</label>
259 <label for="rhodecode_pr_merge_enabled${suffix}">${_('Enable server-side merge for pull requests')}</label>
260 </div>
260 </div>
261 <div class="label">
261 <div class="label">
262 <span class="help-block">${_('Note: when this feature is enabled, it only runs hooks defined in the rcextension package. Custom hooks added on the Admin -> Settings -> Hooks page will not be run when pull requests are automatically merged from the web interface.')}</span>
262 <span class="help-block">${_('Note: when this feature is enabled, it only runs hooks defined in the rcextension package. Custom hooks added on the Admin -> Settings -> Hooks page will not be run when pull requests are automatically merged from the web interface.')}</span>
263 </div>
263 </div>
264 <div class="checkbox">
264 <div class="checkbox">
265 ${h.checkbox('rhodecode_use_outdated_comments' + suffix, 'True', **kwargs)}
265 ${h.checkbox('rhodecode_use_outdated_comments' + suffix, 'True', **kwargs)}
266 <label for="rhodecode_use_outdated_comments${suffix}">${_('Invalidate and relocate inline comments during update')}</label>
266 <label for="rhodecode_use_outdated_comments${suffix}">${_('Invalidate and relocate inline comments during update')}</label>
267 </div>
267 </div>
268 <div class="label">
268 <div class="label">
269 <span class="help-block">${_('During the update of a pull request, the position of inline comments will be updated and outdated inline comments will be hidden.')}</span>
269 <span class="help-block">${_('During the update of a pull request, the position of inline comments will be updated and outdated inline comments will be hidden.')}</span>
270 </div>
270 </div>
271 </div>
271 </div>
272 </div>
272 </div>
273 % endif
273 % endif
274
274
275 </%def>
275 </%def>
General Comments 0
You need to be logged in to leave comments. Login now