diff --git a/softpack_core/schemas/environment.py b/softpack_core/schemas/environment.py index 0801b59..59d9733 100644 --- a/softpack_core/schemas/environment.py +++ b/softpack_core/schemas/environment.py @@ -163,6 +163,19 @@ def validate(self) -> Union[None, InvalidInputError]: "dash, and underscore" ) + valid_dirs = [ + Artifacts.users_folder_name, + Artifacts.groups_folder_name, + ] + if not any(self.path.startswith(dir + "/") for dir in valid_dirs): + return InvalidInputError(message="Invalid path") + + if not re.fullmatch(r"^[^/]+/[a-zA-Z0-9_-]+$", self.path): + return InvalidInputError( + message="user/group subdirectory must only contain " + "alphanumerics, dash, and underscore" + ) + return None @classmethod @@ -182,8 +195,8 @@ def from_path(cls, environment_path: str) -> 'EnvironmentInput': return EnvironmentInput( name=environment_name, path="/".join(environment_dirs), - description="", - packages=list(), + description="placeholder description", + packages=[PackageInput("placeholder")], ) @@ -247,13 +260,14 @@ def create(cls, env: EnvironmentInput) -> CreateResponse: # type: ignore Returns: A message confirming the success or failure of the operation. """ - input_err = env.validate() - if input_err is not None: - return input_err - versionless_name = env.name version = 1 + if not versionless_name: + return InvalidInputError( + message="environment name must not be blank" + ) + while True: env.name = versionless_name + "-" + str(version) response = cls.create_new_env( @@ -319,15 +333,12 @@ def create_new_env( CreateResponse: a CreateEnvironmentSuccess on success, or one of (InvalidInputError, EnvironmentAlreadyExistsError) on error. """ - # Check if a valid path has been provided. TODO: improve this to check - # that they can only create stuff in their own users folder, or in + # TODO: improve this to check + # that users can only create stuff in their own users folder, or in # group folders of unix groups they belong to. - valid_dirs = [ - cls.artifacts.users_folder_name, - cls.artifacts.groups_folder_name, - ] - if not any(env.path.startswith(dir) for dir in valid_dirs): - return InvalidInputError(message="Invalid path") + input_err = env.validate() + if input_err is not None: + return input_err # Check if an env with same name already exists at given path if cls.artifacts.get(Path(env.path), env.name): diff --git a/tests/integration/test_environment.py b/tests/integration/test_environment.py index aa314b4..6eb3a9f 100644 --- a/tests/integration/test_environment.py +++ b/tests/integration/test_environment.py @@ -124,8 +124,19 @@ def test_create_name_dashes_and_number_first_allowed( assert isinstance(result, CreateEnvironmentSuccess) -def test_create_path_invalid_disallowed(httpx_post, testable_env_input): - testable_env_input.path = "invalid/path" +@pytest.mark.parametrize( + "path", + [ + "invalid/path", + "users/", + "users/username/foo", + "users/abc123/very/nested", + "users/../nasty", + "users/user name", + ], +) +def test_create_path_invalid_disallowed(httpx_post, testable_env_input, path): + testable_env_input.path = path result = Environment.create(testable_env_input) assert isinstance(result, InvalidInputError)