##// END OF EJS Templates
Adds configuration settings to limit valid repository path (#1415)....
Jean-Philippe Lang -
r13191:13f9ccaed853
parent child
Show More
@@ -152,7 +152,7 module RepositoriesHelper
152 def subversion_field_tags(form, repository)
152 def subversion_field_tags(form, repository)
153 content_tag('p', form.text_field(:url, :size => 60, :required => true,
153 content_tag('p', form.text_field(:url, :size => 60, :required => true,
154 :disabled => !repository.safe_attribute?('url')) +
154 :disabled => !repository.safe_attribute?('url')) +
155 content_tag('em', '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)', :class => 'info')) +
155 scm_path_info_tag(repository)) +
156 content_tag('p', form.text_field(:login, :size => 30)) +
156 content_tag('p', form.text_field(:login, :size => 30)) +
157 content_tag('p', form.password_field(
157 content_tag('p', form.password_field(
158 :password, :size => 30, :name => 'ignore',
158 :password, :size => 30, :name => 'ignore',
@@ -165,7 +165,8 module RepositoriesHelper
165 content_tag('p', form.text_field(
165 content_tag('p', form.text_field(
166 :url, :label => l(:field_path_to_repository),
166 :url, :label => l(:field_path_to_repository),
167 :size => 60, :required => true,
167 :size => 60, :required => true,
168 :disabled => !repository.safe_attribute?('url'))) +
168 :disabled => !repository.safe_attribute?('url')) +
169 scm_path_info_tag(repository)) +
169 scm_log_encoding_tag(form, repository)
170 scm_log_encoding_tag(form, repository)
170 end
171 end
171
172
@@ -175,7 +176,7 module RepositoriesHelper
175 :size => 60, :required => true,
176 :size => 60, :required => true,
176 :disabled => !repository.safe_attribute?('url')
177 :disabled => !repository.safe_attribute?('url')
177 ) +
178 ) +
178 content_tag('em', l(:text_mercurial_repository_note), :class => 'info')) +
179 scm_path_info_tag(repository)) +
179 scm_path_encoding_tag(form, repository)
180 scm_path_encoding_tag(form, repository)
180 end
181 end
181
182
@@ -185,7 +186,7 module RepositoriesHelper
185 :size => 60, :required => true,
186 :size => 60, :required => true,
186 :disabled => !repository.safe_attribute?('url')
187 :disabled => !repository.safe_attribute?('url')
187 ) +
188 ) +
188 content_tag('em', l(:text_git_repository_note), :class => 'info')) +
189 scm_path_info_tag(repository)) +
189 scm_path_encoding_tag(form, repository) +
190 scm_path_encoding_tag(form, repository) +
190 content_tag('p', form.check_box(
191 content_tag('p', form.check_box(
191 :extra_report_last_commit,
192 :extra_report_last_commit,
@@ -198,7 +199,8 module RepositoriesHelper
198 :root_url,
199 :root_url,
199 :label => l(:field_cvsroot),
200 :label => l(:field_cvsroot),
200 :size => 60, :required => true,
201 :size => 60, :required => true,
201 :disabled => !repository.safe_attribute?('root_url'))) +
202 :disabled => !repository.safe_attribute?('root_url')) +
203 scm_path_info_tag(repository)) +
202 content_tag('p', form.text_field(
204 content_tag('p', form.text_field(
203 :url,
205 :url,
204 :label => l(:field_cvs_module),
206 :label => l(:field_cvs_module),
@@ -212,7 +214,8 module RepositoriesHelper
212 content_tag('p', form.text_field(
214 content_tag('p', form.text_field(
213 :url, :label => l(:field_path_to_repository),
215 :url, :label => l(:field_path_to_repository),
214 :size => 60, :required => true,
216 :size => 60, :required => true,
215 :disabled => !repository.safe_attribute?('url'))) +
217 :disabled => !repository.safe_attribute?('url')) +
218 scm_path_info_tag(repository)) +
216 scm_log_encoding_tag(form, repository)
219 scm_log_encoding_tag(form, repository)
217 end
220 end
218
221
@@ -220,10 +223,29 module RepositoriesHelper
220 content_tag('p', form.text_field(
223 content_tag('p', form.text_field(
221 :url, :label => l(:field_root_directory),
224 :url, :label => l(:field_root_directory),
222 :size => 60, :required => true,
225 :size => 60, :required => true,
223 :disabled => !repository.safe_attribute?('url'))) +
226 :disabled => !repository.safe_attribute?('url')) +
227 scm_path_info_tag(repository)) +
224 scm_path_encoding_tag(form, repository)
228 scm_path_encoding_tag(form, repository)
225 end
229 end
226
230
231 def scm_path_info_tag(repository)
232 text = scm_path_info(repository)
233 if text.present?
234 content_tag('em', text, :class => 'info')
235 else
236 ''
237 end
238 end
239
240 def scm_path_info(repository)
241 scm_name = repository.scm_name.to_s.downcase
242
243 info_from_config = Redmine::Configuration["scm_#{scm_name}_path_info"].presence
244 return info_from_config.html_safe if info_from_config
245
246 l("text_#{scm_name}_repository_note", :default => '')
247 end
248
227 def scm_log_encoding_tag(form, repository)
249 def scm_log_encoding_tag(form, repository)
228 select = form.select(
250 select = form.select(
229 :log_encoding,
251 :log_encoding,
@@ -45,6 +45,7 class Repository < ActiveRecord::Base
45 validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
45 validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
46 # Checks if the SCM is enabled when creating a repository
46 # Checks if the SCM is enabled when creating a repository
47 validate :repo_create_validation, :on => :create
47 validate :repo_create_validation, :on => :create
48 validate :validate_repository_path
48 attr_protected :id
49 attr_protected :id
49
50
50 safe_attributes 'identifier',
51 safe_attributes 'identifier',
@@ -458,6 +459,18 class Repository < ActiveRecord::Base
458
459
459 protected
460 protected
460
461
462 # Validates repository url based against an optional regular expression
463 # that can be set in the Redmine configuration file.
464 def validate_repository_path(attribute=:url)
465 regexp = Redmine::Configuration["scm_#{scm_name.to_s.downcase}_path_regexp"]
466 if changes[attribute] && regexp.present?
467 regexp = regexp.to_s.strip.gsub('%project%') {Regexp.escape(project.try(:identifier).to_s)}
468 unless send(attribute).to_s.match(Regexp.new("\\A#{regexp}\\z"))
469 errors.add(attribute, :invalid)
470 end
471 end
472 end
473
461 def check_default
474 def check_default
462 if !is_default? && set_as_default?
475 if !is_default? && set_as_default?
463 self.is_default = true
476 self.is_default = true
@@ -192,6 +192,14 class Repository::Cvs < Repository
192 @current_revision_number = nil
192 @current_revision_number = nil
193 end
193 end
194
194
195 protected
196
197 # Overrides Repository#validate_repository_path to validate
198 # against root_url attribute.
199 def validate_repository_path(attribute=:root_url)
200 super(attribute)
201 end
202
195 private
203 private
196
204
197 # Returns the next revision number to assign to a CVS changeset
205 # Returns the next revision number to assign to a CVS changeset
@@ -108,6 +108,33 default:
108 scm_bazaar_command:
108 scm_bazaar_command:
109 scm_darcs_command:
109 scm_darcs_command:
110
110
111 # SCM paths validation.
112 #
113 # You can configure a regular expression for each SCM that will be used to
114 # validate the path of new repositories (eg. path entered by users with the
115 # "Manage repositories" permission and path returned by reposman.rb).
116 # The regexp will be wrapped with \A \z, so it must match the whole path.
117 # And the regexp is case sensitive.
118 #
119 # You can match the project identifier by using %project% in the regexp.
120 #
121 # You can also set a custom hint message for each SCM that will be displayed
122 # on the repository form instead of the default one.
123 #
124 # Examples:
125 # scm_subversion_path_regexp: file:///svnpath/[a-z0-9_]+
126 # scm_subversion_path_info: SVN URL (eg. file:///svnpath/foo)
127 #
128 # scm_git_path_regexp: /gitpath/%project%(\.[a-z0-9_])?/
129 #
130 scm_subversion_path_regexp:
131 scm_mercurial_path_regexp:
132 scm_git_path_regexp:
133 scm_cvs_path_regexp:
134 scm_bazaar_path_regexp:
135 scm_darcs_path_regexp:
136 scm_filesystem_path_regexp:
137
111 # Absolute path to the SCM commands errors (stderr) log file.
138 # Absolute path to the SCM commands errors (stderr) log file.
112 # The default is to log in the 'log' directory of your Redmine instance.
139 # The default is to log in the 'log' directory of your Redmine instance.
113 # Example:
140 # Example:
@@ -1052,6 +1052,7 en:
1052 text_zoom_out: Zoom out
1052 text_zoom_out: Zoom out
1053 text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
1053 text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
1054 text_scm_path_encoding_note: "Default: UTF-8"
1054 text_scm_path_encoding_note: "Default: UTF-8"
1055 text_subversion_repository_note: "Examples: file:///, http://, https://, svn://, svn+[tunnelscheme]://"
1055 text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
1056 text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
1056 text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
1057 text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
1057 text_scm_command: Command
1058 text_scm_command: Command
@@ -1072,8 +1072,9 fr:
1072 text_zoom_out: Zoom arrière
1072 text_zoom_out: Zoom arrière
1073 text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardΓ© qui sera perdu si vous quittez la page."
1073 text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardΓ© qui sera perdu si vous quittez la page."
1074 text_scm_path_encoding_note: "DΓ©faut : UTF-8"
1074 text_scm_path_encoding_note: "DΓ©faut : UTF-8"
1075 text_git_repository_note: "Le dΓ©pΓ΄t est vide et local (exemples : /gitrepo, c:\\gitrepo)"
1075 text_subversion_repository_note: "Exemples (en fonction des protocoles supportΓ©s) : file:///, http://, https://, svn://, svn+[tunnelscheme]://"
1076 text_mercurial_repository_note: "DΓ©pΓ΄t local (exemples : /hgrepo, c:\\hgrepo)"
1076 text_git_repository_note: "Chemin vers un dΓ©pΓ΄t vide et local (exemples : /gitrepo, c:\\gitrepo)"
1077 text_mercurial_repository_note: "Chemin vers un dΓ©pΓ΄t local (exemples : /hgrepo, c:\\hgrepo)"
1077 text_scm_command: Commande
1078 text_scm_command: Commande
1078 text_scm_command_version: Version
1079 text_scm_command_version: Version
1079 text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. Redémarrer l'application après modification.
1080 text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. Redémarrer l'application après modification.
@@ -58,6 +58,7 module Redmine
58 end
58 end
59 end
59 end
60
60
61 check_regular_expressions
61 @config
62 @config
62 end
63 end
63
64
@@ -112,6 +113,20 module Redmine
112 @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
113 @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
113 end
114 end
114 end
115 end
116
117 # Checks the validness of regular expressions set for repository paths at startup
118 def check_regular_expressions
119 @config.each do |name, value|
120 if value.present? && name =~ /^scm_.+_path_regexp$/
121 begin
122 Regexp.new value.to_s.strip
123 rescue => e
124 $stderr.puts "Invalid regular expression set as #{name} setting in your Redmine configuration file:\n#{e.message}"
125 exit 1
126 end
127 end
128 end
129 end
115 end
130 end
116 end
131 end
117 end
132 end
@@ -93,6 +93,24 class RepositoryCvsTest < ActiveSupport::TestCase
93 assert_include str, repo.errors.full_messages
93 assert_include str, repo.errors.full_messages
94 end
94 end
95
95
96 def test_root_url_should_be_validated_against_regexp_set_in_configuration
97 Redmine::Configuration.with 'scm_cvs_path_regexp' => '/cvspath/[a-z]+' do
98 repo = Repository::Cvs.new(
99 :project => @project,
100 :identifier => 'test',
101 :log_encoding => 'UTF-8',
102 :path_encoding => '',
103 :url => MODULE_NAME
104 )
105 repo.root_url = '/wrong_path'
106 assert !repo.valid?
107 assert repo.errors[:root_url].present?
108
109 repo.root_url = '/cvspath/foo'
110 assert repo.valid?
111 end
112 end
113
96 if File.directory?(REPOSITORY_PATH)
114 if File.directory?(REPOSITORY_PATH)
97 def test_fetch_changesets_from_scratch
115 def test_fetch_changesets_from_scratch
98 assert_equal 0, @repository.changesets.count
116 assert_equal 0, @repository.changesets.count
@@ -57,6 +57,37 class RepositorySubversionTest < ActiveSupport::TestCase
57 end
57 end
58 end
58 end
59
59
60 def test_url_should_be_validated_against_regexp_set_in_configuration
61 Redmine::Configuration.with 'scm_subversion_path_regexp' => 'file:///svnpath/[a-z]+' do
62 repo = Repository::Subversion.new(:project => @project, :identifier => 'test')
63 repo.url = 'http://foo'
64 assert !repo.valid?
65 assert repo.errors[:url].present?
66
67 repo.url = 'file:///svnpath/foo/bar'
68 assert !repo.valid?
69 assert repo.errors[:url].present?
70
71 repo.url = 'file:///svnpath/foo'
72 assert repo.valid?
73 end
74 end
75
76 def test_url_should_be_validated_against_regexp_set_in_configuration_with_project_identifier
77 Redmine::Configuration.with 'scm_subversion_path_regexp' => 'file:///svnpath/%project%(\.[a-z]+)?' do
78 repo = Repository::Subversion.new(:project => @project, :identifier => 'test')
79 repo.url = 'file:///svnpath/invalid'
80 assert !repo.valid?
81 assert repo.errors[:url].present?
82
83 repo.url = 'file:///svnpath/subproject1'
84 assert repo.valid?
85
86 repo.url = 'file:///svnpath/subproject1.foo'
87 assert repo.valid?
88 end
89 end
90
60 if repository_configured?('subversion')
91 if repository_configured?('subversion')
61 def test_fetch_changesets_from_scratch
92 def test_fetch_changesets_from_scratch
62 assert_equal 0, @repository.changesets.count
93 assert_equal 0, @repository.changesets.count
General Comments 0
You need to be logged in to leave comments. Login now