Skip to content

Commit

Permalink
Tighten validation of environment inputs (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
sersorrel authored Feb 7, 2024
1 parent 08aaae2 commit 17c5908
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 16 deletions.
39 changes: 25 additions & 14 deletions softpack_core/schemas/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")],
)


Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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):
Expand Down
15 changes: 13 additions & 2 deletions tests/integration/test_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down

0 comments on commit 17c5908

Please sign in to comment.