avoid breaking out into filestructure
This commit is contained in:
parent
564d95a5c2
commit
a0f972f38a
34
app.py
34
app.py
@ -15,6 +15,7 @@ import geoip2.database
|
|||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
from urllib.parse import urlparse, unquote
|
from urllib.parse import urlparse, unquote
|
||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
import qrcode
|
import qrcode
|
||||||
import base64
|
import base64
|
||||||
@ -24,6 +25,7 @@ import analytics as a
|
|||||||
import folder_secret_config_editor as fsce
|
import folder_secret_config_editor as fsce
|
||||||
|
|
||||||
app_config = auth.return_app_config()
|
app_config = auth.return_app_config()
|
||||||
|
BASE_DIR = os.path.realpath(app_config['BASE_DIR'])
|
||||||
|
|
||||||
cache_audio = diskcache.Cache('./filecache_audio', size_limit= app_config['filecache_size_limit_audio'] * 1024**3)
|
cache_audio = diskcache.Cache('./filecache_audio', size_limit= app_config['filecache_size_limit_audio'] * 1024**3)
|
||||||
cache_image = diskcache.Cache('./filecache_image', size_limit= app_config['filecache_size_limit_image'] * 1024**3)
|
cache_image = diskcache.Cache('./filecache_image', size_limit= app_config['filecache_size_limit_image'] * 1024**3)
|
||||||
@ -90,6 +92,27 @@ def get_cached_image(size):
|
|||||||
resized_img.save(img_byte_arr, format='PNG')
|
resized_img.save(img_byte_arr, format='PNG')
|
||||||
return img_byte_arr.getvalue()
|
return img_byte_arr.getvalue()
|
||||||
|
|
||||||
|
def check_path(access_path: str) -> Path:
|
||||||
|
"""
|
||||||
|
Take an absolute access_path, then ensure it lives inside BASE_DIR.
|
||||||
|
Raises ValueError or PermissionError on failure.
|
||||||
|
"""
|
||||||
|
p = Path(access_path)
|
||||||
|
if not p.is_absolute():
|
||||||
|
raise ValueError(f"Path {access_path} is not a valid absolute path")
|
||||||
|
|
||||||
|
# Resolve symlinks & eliminate “..” components
|
||||||
|
candidate = p.resolve()
|
||||||
|
base = Path(BASE_DIR).resolve()
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Will raise ValueError if candidate is not under base
|
||||||
|
candidate.relative_to(base)
|
||||||
|
except ValueError:
|
||||||
|
raise PermissionError(f"Access to {access_path} is forbidden")
|
||||||
|
|
||||||
|
return candidate
|
||||||
|
|
||||||
def list_directory_contents(directory, subpath):
|
def list_directory_contents(directory, subpath):
|
||||||
"""
|
"""
|
||||||
List only the immediate contents of the given directory.
|
List only the immediate contents of the given directory.
|
||||||
@ -236,6 +259,12 @@ def api_browse(subpath):
|
|||||||
directory = os.path.join(base_path, *relative_parts)
|
directory = os.path.join(base_path, *relative_parts)
|
||||||
|
|
||||||
playfile = None
|
playfile = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
directory = check_path(directory)
|
||||||
|
except (ValueError, PermissionError) as e:
|
||||||
|
return jsonify({'error': str(e)}), 403
|
||||||
|
|
||||||
# Check if the constructed directory exists.
|
# Check if the constructed directory exists.
|
||||||
if not os.path.isdir(directory):
|
if not os.path.isdir(directory):
|
||||||
# Assume the last segment is a filename; remove it.
|
# Assume the last segment is a filename; remove it.
|
||||||
@ -270,6 +299,11 @@ def serve_file(subpath):
|
|||||||
root, *relative_parts = subpath.split('/')
|
root, *relative_parts = subpath.split('/')
|
||||||
base_path = session['folders'].get(root)
|
base_path = session['folders'].get(root)
|
||||||
full_path = os.path.join(base_path or '', *relative_parts)
|
full_path = os.path.join(base_path or '', *relative_parts)
|
||||||
|
|
||||||
|
try:
|
||||||
|
full_path = check_path(full_path)
|
||||||
|
except (ValueError, PermissionError) as e:
|
||||||
|
return jsonify({'error': str(e)}), 403
|
||||||
|
|
||||||
if not os.path.isfile(full_path):
|
if not os.path.isfile(full_path):
|
||||||
app.logger.error(f"File not found: {full_path}")
|
app.logger.error(f"File not found: {full_path}")
|
||||||
|
|||||||
@ -213,7 +213,12 @@ function loadDirectory(subpath) {
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
clearTimeout(spinnerTimer);
|
clearTimeout(spinnerTimer);
|
||||||
hideSpinner();
|
hideSpinner();
|
||||||
renderContent(data);
|
if (data.breadcrumbs) {
|
||||||
|
renderContent(data);
|
||||||
|
} else if (data.error) {
|
||||||
|
document.getElementById('content').innerHTML = `<div class="alert alert-warning">${data.error}</div>`;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (data.playfile) {
|
if (data.playfile) {
|
||||||
const playFileLink = document.querySelector(`.play-file[data-url="${data.playfile}"]`);
|
const playFileLink = document.querySelector(`.play-file[data-url="${data.playfile}"]`);
|
||||||
if (playFileLink) {
|
if (playFileLink) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user