Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/wiki.rb')
-rw-r--r--app/models/wiki.rb86
1 files changed, 75 insertions, 11 deletions
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index b3f09b20463..b29c43bcfe1 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -13,43 +13,65 @@ class Wiki
markdown: {
name: 'Markdown',
default_extension: :md,
+ extension_regex: Regexp.new('md|mkdn?|mdown|markdown', 'i'),
created_by_user: true
},
rdoc: {
name: 'RDoc',
default_extension: :rdoc,
+ extension_regex: Regexp.new('rdoc', 'i'),
created_by_user: true
},
asciidoc: {
name: 'AsciiDoc',
default_extension: :asciidoc,
+ extension_regex: Regexp.new('adoc|asciidoc', 'i'),
created_by_user: true
},
org: {
name: 'Org',
default_extension: :org,
+ extension_regex: Regexp.new('org', 'i'),
created_by_user: true
},
textile: {
name: 'Textile',
- default_extension: :textile
+ default_extension: :textile,
+ extension_regex: Regexp.new('textile', 'i')
},
creole: {
name: 'Creole',
- default_extension: :creole
+ default_extension: :creole,
+ extension_regex: Regexp.new('creole', 'i')
},
rest: {
name: 'reStructuredText',
- default_extension: :rst
+ default_extension: :rst,
+ extension_regex: Regexp.new('re?st(\.txt)?', 'i')
},
mediawiki: {
name: 'MediaWiki',
- default_extension: :mediawiki
+ default_extension: :mediawiki,
+ extension_regex: Regexp.new('(media)?wiki', 'i')
+ },
+ pod: {
+ name: 'Pod',
+ default_extension: :pod,
+ extension_regex: Regexp.new('pod', 'i')
+ },
+ plaintext: {
+ name: 'Plain Text',
+ default_extension: :txt,
+ extension_regex: Regexp.new('txt', 'i')
}
}.freeze unless defined?(MARKUPS)
VALID_USER_MARKUPS = MARKUPS.select { |_, v| v[:created_by_user] }.freeze unless defined?(VALID_USER_MARKUPS)
+ unless defined?(ALLOWED_EXTENSIONS_REGEX)
+ ALLOWED_EXTENSIONS_REGEX = Regexp.union(MARKUPS.map { |key, value| value[:extension_regex] }).freeze
+ end
+
CouldNotCreateWikiError = Class.new(StandardError)
HOMEPAGE = 'home'
@@ -205,15 +227,36 @@ class Wiki
end
def create_page(title, content, format = :markdown, message = nil)
- commit = commit_details(:created, message, title)
+ if Feature.enabled?(:gitaly_replace_wiki_create_page, container, default_enabled: :yaml)
+ with_valid_format(format) do |default_extension|
+ if file_exists_by_regex?(title)
+ raise_duplicate_page_error!
+ end
+
+ capture_git_error(:created) do
+ create_wiki_repository unless repository_exists?
+ sanitized_path = sluggified_full_path(title, default_extension)
+ repository.create_file(user, sanitized_path, content, **multi_commit_options(:created, message, title))
+ repository.expire_status_cache if repository.empty?
+ after_wiki_activity
- wiki.write_page(title, format.to_sym, content, commit)
- repository.expire_status_cache if repository.empty?
- after_wiki_activity
+ true
+ rescue Gitlab::Git::Index::IndexError
+ raise_duplicate_page_error!
+ end
+ end
+ else
+ commit = commit_details(:created, message, title)
+
+ wiki.write_page(title, format.to_sym, content, commit)
+ repository.expire_status_cache if repository.empty?
+ after_wiki_activity
- true
+ true
+ end
rescue Gitlab::Git::Wiki::DuplicatePageError => e
- @error_message = "Duplicate page: #{e.message}"
+ @error_message = _("Duplicate page: %{error_message}" % { error_message: e.message })
+
false
end
@@ -393,12 +436,33 @@ class Wiki
yield default_extension
end
+ def file_exists_by_regex?(title)
+ return false unless repository_exists?
+
+ escaped_title = Regexp.escape(sluggified_title(title))
+ regex = Regexp.new("^#{escaped_title}\.#{ALLOWED_EXTENSIONS_REGEX}$", 'i')
+
+ repository.ls_files('HEAD').any? { |s| s =~ regex }
+ end
+
+ def raise_duplicate_page_error!
+ raise Gitlab::Git::Wiki::DuplicatePageError, _('A page with that title already exists')
+ end
+
def sluggified_full_path(title, extension)
sluggified_title(title) + '.' + extension
end
def sluggified_title(title)
- Gitlab::EncodingHelper.encode_utf8_no_detect(title).tr(' ', '-')
+ utf8_encoded_title = Gitlab::EncodingHelper.encode_utf8_no_detect(title)
+
+ sanitized_title(utf8_encoded_title).tr(' ', '-')
+ end
+
+ def sanitized_title(title)
+ clean_absolute_path = File.expand_path(title, '/')
+
+ Pathname.new(clean_absolute_path).relative_path_from('/').to_s
end
end