Skip to content

Commit

Permalink
[api] Refactor /mkdir API with better validation checks
Browse files Browse the repository at this point in the history
  • Loading branch information
Harshg999 committed Feb 6, 2025
1 parent 34f8b8d commit 82b786c
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 4 deletions.
26 changes: 23 additions & 3 deletions apps/filebrowser/src/filebrowser/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -536,14 +536,34 @@ def upload_file(request):

@api_error_handler
def mkdir(request):
"""
Create a new directory at the specified path with the given name.
Args:
request (HttpRequest): The HTTP request object containing the data.
Returns:
A HttpResponse with a status code and message indicating the success or failure of the directory creation.
"""
# TODO: Check if this needs to be a PUT request
path = request.POST.get('path')
name = request.POST.get('name')

if name and (posixpath.sep in name or "#" in name):
return HttpResponse(f"Error creating {name} directory. Slashes or hashes are not allowed in directory name.", status=400)
# Check if source and destination paths are provided
if not path or not name:
return HttpResponse("Missing required parameters: path and name are required.", status=400)

# Validate the 'name' parameter for invalid characters
if posixpath.sep in name or "#" in name:
return HttpResponse(f"Slashes or hashes are not allowed in directory name. Please choose a different name.", status=400)

dir_path = request.fs.join(path, name)

# Check if the directory already exists
if request.fs.isdir(dir_path):
return HttpResponse(f"Error creating {name} directory: Directory already exists.", status=409)

request.fs.mkdir(request.fs.join(path, name))
request.fs.mkdir(dir_path)
return HttpResponse(status=201)


Expand Down
79 changes: 78 additions & 1 deletion apps/filebrowser/src/filebrowser/api_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

from django.core.files.uploadedfile import SimpleUploadedFile

from filebrowser.api import get_all_filesystems, rename, upload_file
from filebrowser.api import get_all_filesystems, mkdir, rename, upload_file
from filebrowser.conf import (
MAX_FILE_SIZE_UPLOAD_LIMIT,
RESTRICT_FILE_EXTENSIONS,
Expand Down Expand Up @@ -330,6 +330,83 @@ def test_file_upload_failure(self):
reset()


class TestMkdirAPI:
def test_mkdir_success(self):
request = Mock(
method='POST',
POST={'path': 's3a://test-bucket/test-user/', 'name': 'new_dir'},
fs=Mock(
mkdir=Mock(),
isdir=Mock(return_value=False),
join=Mock(return_value='s3a://test-bucket/test-user/new_dir'),
),
)
response = mkdir(request)

assert response.status_code == 201
request.fs.mkdir.assert_called_once_with('s3a://test-bucket/test-user/new_dir')

def test_mkdir_directory_exists(self):
request = Mock(
method='POST',
POST={'path': 's3a://test-bucket/test-user/', 'name': 'new_dir'},
fs=Mock(
mkdir=Mock(),
isdir=Mock(return_value=True),
join=Mock(return_value='s3a://test-bucket/test-user/new_dir'),
),
)
response = mkdir(request)

assert response.status_code == 409
assert response.content.decode('utf-8') == 'Error creating new_dir directory: Directory already exists.'

def test_mkdir_invalid_name(self):
request = Mock(
method='POST',
POST={'path': 's3a://test-bucket/test-user/', 'name': 'new#dir'},
fs=Mock(
mkdir=Mock(),
isdir=Mock(return_value=False),
join=Mock(return_value='s3a://test-bucket/test-user/new#dir'),
),
)
response = mkdir(request)

assert response.status_code == 400
assert response.content.decode('utf-8') == 'Slashes or hashes are not allowed in directory name. Please choose a different name.'

def test_mkdir_no_path(self):
request = Mock(
method='POST',
POST={'name': 'new_dir'},
fs=Mock(
mkdir=Mock(),
isdir=Mock(return_value=False),
join=Mock(return_value='s3a://test-bucket/test-user/new_dir'),
),
)
response = mkdir(request)

assert response.status_code == 400
assert response.content.decode('utf-8') == 'Missing required parameters: path and name are required.'

def test_mkdir_no_name(self):
request = Mock(
method='POST',
POST={'path': 's3a://test-bucket/test-user/'},
fs=Mock(
mkdir=Mock(),
isdir=Mock(return_value=False),
join=Mock(return_value='s3a://test-bucket/test-user/new_dir'),
),
)
response = mkdir(request)

assert response.status_code == 400
assert response.content.decode('utf-8') == 'Missing required parameters: path and name are required.'


class TestRenameAPI:
def test_rename_success(self):
request = Mock(
Expand Down

0 comments on commit 82b786c

Please sign in to comment.