Commit 3be9d2c4 authored by Ben Ford's avatar Ben Ford Committed by Douwe Maan

Add ability to create directories in the editor

Simply type a name with a `/` directory separator and new directories
will be created. This does not do the fancy UI work that github.com
does, but it will get the job done.

I could not find tests for file creation, so I didn't add a test for
this slight behaviour modification. I did test directory traversals
though, using both absolute paths like `/tmp/foo.txt` and relative paths
like `../../foo.txt`. Neither case escaped the repository, though
attempting to traverse with a relative path resulted in a 500 error that
did not affect application stability upon reload.
parent ae99720a
Please view this file on the master branch, on stable branches it's out of date.
development
- Adds ability to create directories using the web editor
v 8.2.0 (unreleased)
- Improved performance of replacing references in comments
- Show last project commit to default branch on project home page
......
......@@ -50,7 +50,7 @@
.editor-file-name {
.new-file-name {
display: inline-block;
width: 200px;
width: 450px;
}
.form-control {
......
......@@ -161,7 +161,7 @@ class Projects::BlobController < Projects::ApplicationController
if params[:file].present?
params[:file_name] = params[:file].original_filename
end
File.join(@path, File.basename(params[:file_name]))
File.join(@path, params[:file_name])
else
@path
end
......
......@@ -5,5 +5,16 @@ module Files
def commit
repository.commit_dir(current_user, @file_path, @commit_message, @target_branch)
end
def validate
super
unless @file_path =~ Gitlab::Regex.file_path_regex
raise_error(
'Your changes could not be committed, because the file path ' +
Gitlab::Regex.file_path_regex_message
)
end
end
end
end
......@@ -9,12 +9,17 @@ module Files
def validate
super
file_name = File.basename(@file_path)
if @file_path =~ Gitlab::Regex.directory_traversal_regex
raise_error(
'Your changes could not be committed, because the file name ' +
Gitlab::Regex.directory_traversal_regex_message
)
end
unless file_name =~ Gitlab::Regex.file_name_regex
unless @file_path =~ Gitlab::Regex.file_path_regex
raise_error(
'Your changes could not be committed, because the file name ' +
Gitlab::Regex.file_name_regex_message
Gitlab::Regex.file_path_regex_message
)
end
......
......@@ -90,6 +90,16 @@ Feature: Project Source Browse Files
Then I am on the new file page
And I see a commit error message
@javascript
Scenario: I can create file with a directory name
Given I click on "New file" link in repo
And I fill the new file name with a new directory
And I edit code
And I fill the commit message
And I click on "Commit changes"
Then I am redirected to the new file with directory
And I should see its new content
@javascript
Scenario: I can edit file
Given I click on ".gitignore" file in repo
......
......@@ -78,6 +78,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
fill_in :file_name, with: 'Spaces Not Allowed'
end
step 'I fill the new file name with a new directory' do
fill_in :file_name, with: new_file_name_with_directory
end
step 'I fill the commit message' do
fill_in :commit_message, with: 'Not yet a commit message.', visible: true
end
......@@ -238,6 +242,11 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
@project.namespace, @project, 'master/' + new_file_name))
end
step 'I am redirected to the new file with directory' do
expect(current_path).to eq(namespace_project_blob_path(
@project.namespace, @project, 'master/' + new_file_name_with_directory))
end
step 'I am redirected to the new file on new branch' do
expect(current_path).to eq(namespace_project_blob_path(
@project.namespace, @project, 'new_branch_name/' + new_file_name))
......@@ -335,6 +344,12 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
'not_a_file.md'
end
# Constant value that is a valid filename with directory and
# not a filename present at root of the seed repository.
def new_file_name_with_directory
'foo/bar/baz.txt'
end
# Constant value that is a valid directory and
# not a directory present at root of the seed repository.
def new_dir_name
......
......@@ -51,6 +51,23 @@ module Gitlab
"can contain only letters, digits, '_', '-' and '.'. "
end
def file_path_regex
@file_path_regex ||= /\A[a-zA-Z0-9_\-\.\/]*\z/.freeze
end
def file_path_regex_message
"can contain only letters, digits, '_', '-' and '.'. Separate directories with a '/'. "
end
def directory_traversal_regex
@directory_traversal_regex ||= /\.{2}/.freeze
end
def directory_traversal_regex_message
"cannot include directory traversal. "
end
def archive_formats_regex
# |zip|tar| tar.gz | tar.bz2 |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment