from whoosh.searching import Hit
-class FilenameContainsPathError(Exception):
- def __init__(self, message="Specified filename contains path information"):
+class InvalidFilenameError(Exception):
+ def __init__(self, message="The specified filename is invalid"):
self.message = message
super().__init__(self.message)
def __init__(
self, flatnotes: "Flatnotes", filename: str, new: bool = False
) -> None:
- if not self._is_path_safe(filename):
- raise FilenameContainsPathError
+ if not self._is_valid_filename(filename):
+ raise InvalidFilenameError
self._flatnotes = flatnotes
self._filename = filename
if new and os.path.exists(self.filepath):
@filename.setter
def filename(self, new_filename):
- if not self._is_path_safe(new_filename):
- raise FilenameContainsPathError
+ if not self._is_valid_filename(new_filename):
+ raise InvalidFilenameError
new_filepath = os.path.join(self._flatnotes.dir, new_filename)
os.rename(self.filepath, new_filepath)
self._filename = new_filename
os.remove(self.filepath)
# Functions
- def _is_path_safe(self, filename: str) -> bool:
- """Return False if the declared filename contains path
- information e.g. '../note.md' or 'folder/note.md'."""
- return os.path.split(filename)[0] == ""
+ def _is_valid_filename(self, filename: str) -> bool:
+ r"""Return False if the declared filename contains any of the following
+ characters: <>:"/\|?*"""
+ invalid_chars = r'<>:"/\|?*'
+ return not any(
+ invalid_char in filename for invalid_char in invalid_chars
+ )
class NoteHit(Note):
from error_responses import (
file_exists_response,
file_not_found_response,
- filename_contains_path_response,
+ invalid_filename_response,
)
from fastapi import Depends, FastAPI, HTTPException
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from models import LoginModel, NoteHitModel, NoteModel, NotePatchModel
-from flatnotes import FilenameContainsPathError, Flatnotes, Note
+from flatnotes import InvalidFilenameError, Flatnotes, Note
logging.basicConfig(
format="%(asctime)s [%(levelname)s]: %(message)s",
note = Note(flatnotes, data.filename, new=True)
note.content = data.content
return NoteModel.dump(note, include_content=True)
- except FilenameContainsPathError:
- return filename_contains_path_response
+ except InvalidFilenameError:
+ return invalid_filename_response
except FileExistsError:
return file_exists_response
try:
note = Note(flatnotes, filename)
return NoteModel.dump(note, include_content=include_content)
- except FilenameContainsPathError:
- return filename_contains_path_response
+ except InvalidFilenameError:
+ return invalid_filename_response
except FileNotFoundError:
return file_not_found_response
if new_data.new_content is not None:
note.content = new_data.new_content
return NoteModel.dump(note, include_content=True)
- except FilenameContainsPathError:
- return filename_contains_path_response
+ except InvalidFilenameError:
+ return invalid_filename_response
except FileNotFoundError:
return file_not_found_response
try:
note = Note(flatnotes, filename)
note.delete()
- except FilenameContainsPathError:
- return filename_contains_path_response
+ except InvalidFilenameError:
+ return invalid_filename_response
except FileNotFoundError:
return file_not_found_response