Normalize path returned by /userdata to always use / as separator (#4906)
This commit is contained in:
parent
cb12ad7049
commit
d2247c1e61
|
@ -120,14 +120,14 @@ class UserManager():
|
||||||
async def listuserdata(request):
|
async def listuserdata(request):
|
||||||
directory = request.rel_url.query.get('dir', '')
|
directory = request.rel_url.query.get('dir', '')
|
||||||
if not directory:
|
if not directory:
|
||||||
return web.Response(status=400)
|
return web.Response(status=400, text="Directory not provided")
|
||||||
|
|
||||||
path = self.get_request_user_filepath(request, directory)
|
path = self.get_request_user_filepath(request, directory)
|
||||||
if not path:
|
if not path:
|
||||||
return web.Response(status=403)
|
return web.Response(status=403, text="Invalid directory")
|
||||||
|
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
return web.Response(status=404)
|
return web.Response(status=404, text="Directory not found")
|
||||||
|
|
||||||
recurse = request.rel_url.query.get('recurse', '').lower() == "true"
|
recurse = request.rel_url.query.get('recurse', '').lower() == "true"
|
||||||
full_info = request.rel_url.query.get('full_info', '').lower() == "true"
|
full_info = request.rel_url.query.get('full_info', '').lower() == "true"
|
||||||
|
@ -143,17 +143,21 @@ class UserManager():
|
||||||
if full_info:
|
if full_info:
|
||||||
results = [
|
results = [
|
||||||
{
|
{
|
||||||
'path': os.path.relpath(x, path),
|
'path': os.path.relpath(x, path).replace(os.sep, '/'),
|
||||||
'size': os.path.getsize(x),
|
'size': os.path.getsize(x),
|
||||||
'modified': os.path.getmtime(x)
|
'modified': os.path.getmtime(x)
|
||||||
} for x in results if os.path.isfile(x)
|
} for x in results if os.path.isfile(x)
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
results = [os.path.relpath(x, path) for x in results if os.path.isfile(x)]
|
results = [
|
||||||
|
os.path.relpath(x, path).replace(os.sep, '/')
|
||||||
|
for x in results
|
||||||
|
if os.path.isfile(x)
|
||||||
|
]
|
||||||
|
|
||||||
split_path = request.rel_url.query.get('split', '').lower() == "true"
|
split_path = request.rel_url.query.get('split', '').lower() == "true"
|
||||||
if split_path and not full_info:
|
if split_path and not full_info:
|
||||||
results = [[x] + x.split(os.sep) for x in results]
|
results = [[x] + x.split('/') for x in results]
|
||||||
|
|
||||||
return web.json_response(results)
|
return web.json_response(results)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import pytest
|
||||||
import os
|
import os
|
||||||
from aiohttp import web
|
from aiohttp import web
|
||||||
from app.user_manager import UserManager
|
from app.user_manager import UserManager
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
pytestmark = (
|
pytestmark = (
|
||||||
pytest.mark.asyncio
|
pytest.mark.asyncio
|
||||||
|
@ -53,7 +54,7 @@ async def test_listuserdata_recursive(aiohttp_client, app, tmp_path):
|
||||||
client = await aiohttp_client(app)
|
client = await aiohttp_client(app)
|
||||||
resp = await client.get("/userdata?dir=test_dir&recurse=true")
|
resp = await client.get("/userdata?dir=test_dir&recurse=true")
|
||||||
assert resp.status == 200
|
assert resp.status == 200
|
||||||
assert set(await resp.json()) == {"file1.txt", os.path.join("subdir", "file2.txt")}
|
assert set(await resp.json()) == {"file1.txt", "subdir/file2.txt"}
|
||||||
|
|
||||||
|
|
||||||
async def test_listuserdata_full_info(aiohttp_client, app, tmp_path):
|
async def test_listuserdata_full_info(aiohttp_client, app, tmp_path):
|
||||||
|
@ -80,7 +81,7 @@ async def test_listuserdata_split_path(aiohttp_client, app, tmp_path):
|
||||||
resp = await client.get("/userdata?dir=test_dir&recurse=true&split=true")
|
resp = await client.get("/userdata?dir=test_dir&recurse=true&split=true")
|
||||||
assert resp.status == 200
|
assert resp.status == 200
|
||||||
assert await resp.json() == [
|
assert await resp.json() == [
|
||||||
[os.path.join("subdir", "file1.txt"), "subdir", "file1.txt"]
|
["subdir/file1.txt", "subdir", "file1.txt"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,3 +89,32 @@ async def test_listuserdata_invalid_directory(aiohttp_client, app):
|
||||||
client = await aiohttp_client(app)
|
client = await aiohttp_client(app)
|
||||||
resp = await client.get("/userdata?dir=")
|
resp = await client.get("/userdata?dir=")
|
||||||
assert resp.status == 400
|
assert resp.status == 400
|
||||||
|
|
||||||
|
|
||||||
|
async def test_listuserdata_normalized_separator(aiohttp_client, app, tmp_path):
|
||||||
|
os_sep = "\\"
|
||||||
|
with patch("os.sep", os_sep):
|
||||||
|
with patch("os.path.sep", os_sep):
|
||||||
|
os.makedirs(tmp_path / "test_dir" / "subdir")
|
||||||
|
with open(tmp_path / "test_dir" / "subdir" / "file1.txt", "w") as f:
|
||||||
|
f.write("test content")
|
||||||
|
|
||||||
|
client = await aiohttp_client(app)
|
||||||
|
resp = await client.get("/userdata?dir=test_dir&recurse=true")
|
||||||
|
assert resp.status == 200
|
||||||
|
result = await resp.json()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert "/" in result[0] # Ensure forward slash is used
|
||||||
|
assert "\\" not in result[0] # Ensure backslash is not present
|
||||||
|
assert result[0] == "subdir/file1.txt"
|
||||||
|
|
||||||
|
# Test with full_info
|
||||||
|
resp = await client.get(
|
||||||
|
"/userdata?dir=test_dir&recurse=true&full_info=true"
|
||||||
|
)
|
||||||
|
assert resp.status == 200
|
||||||
|
result = await resp.json()
|
||||||
|
assert len(result) == 1
|
||||||
|
assert "/" in result[0]["path"] # Ensure forward slash is used
|
||||||
|
assert "\\" not in result[0]["path"] # Ensure backslash is not present
|
||||||
|
assert result[0]["path"] == "subdir/file1.txt"
|
||||||
|
|
Loading…
Reference in New Issue