Skip to content

Commit

Permalink
[doc2] Fix issue where a copy of a shared document in user home becom…
Browse files Browse the repository at this point in the history
…es unreachable

This takes care of an issue where a copy of a shared document ends up in the original owners home directory and becomes unreachable by the user making the copy. With this change these copied files are now put in the home directory of the user that makes the copy instead. If the file to be copied exists in a shared folder the copy will end up in that same shared folder, a user being able to copy such a document implies that the user is also able to browse that directory.
  • Loading branch information
JohanAhlen committed Aug 8, 2024
1 parent ce08dcc commit a2c3090
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 2 deletions.
13 changes: 13 additions & 0 deletions desktop/core/src/desktop/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1276,13 +1276,26 @@ def natural_key(self):
return (self.uuid, self.version, self.is_history)

def copy(self, name, owner, description=None):
# TODO: Check why we choose to mutate the object (x in x.copy()).
# There's some code in api2.py that creates Workflow etc with the mutated reference after copy..
copy_doc = self
source_owner = self.owner
target_directory = self.parent_directory

copy_doc.pk = None
copy_doc.id = None
copy_doc.uuid = uuid_default()
copy_doc.name = name
copy_doc.owner = owner

# If this is a shared document with the user, and it resides in the owner's home directory, we have to put the
# copy in the user's home directory (as the user will not be able to browse the owner's home directory).
# Note that if the document to be copied resides in a shared directory (not home) the copy will end up in the same
# shared directory. Being able to copy it implies that the user can browse the parent directory.
if source_owner != owner and (target_directory is None or target_directory.is_home_directory):
user_home_directory = Document2.objects.get_home_directory(owner)
copy_doc.parent_directory = user_home_directory

if description:
copy_doc.description = description
copy_doc.save()
Expand Down
64 changes: 62 additions & 2 deletions desktop/core/src/desktop/models_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,24 @@ def test_get_remote_storage_home(self):
@pytest.mark.django_db
class TestDocument2(object):
def setup_method(self):
self.client = make_logged_in_client(username="doc2", groupname="doc2", recreate=True, is_superuser=False)
self.default_group = get_default_user_group()

self.client = make_logged_in_client(username="doc2", groupname=self.default_group.name, recreate=True, is_superuser=False)
self.client_not_me = make_logged_in_client(username="not_doc2", groupname=self.default_group.name, recreate=True, is_superuser=False)

self.user = User.objects.get(username="doc2")
self.user_not_me = User.objects.get(username="not_doc2")

# This creates the user directories for the new user
grant_access(self.user.username, self.user.username, "desktop")
grant_access(self.user_not_me.username, self.user_not_me.username, "desktop")

# This creates the user directories for the new users
response = self.client.get('/desktop/api2/doc/')
data = json.loads(response.content)
assert '/' == data['document']['path'], data
response = self.client_not_me.get('/desktop/api2/doc/')
data = json.loads(response.content)
assert '/' == data['document']['path'], data

self.home_dir = Document2.objects.get_home_directory(user=self.user)

Expand Down Expand Up @@ -292,6 +303,55 @@ def copy_remote_dir(self, src, dst, *args, **kwargs):
assert copy_doc.uuid != workflow_doc.uuid
assert copy_workflow.get_data()['workflow']['uuid'] != workflow.get_data()['workflow']['uuid']

def test_copy_of_shared_doc_in_home(self):
user_not_me_home_dir = Document2.objects.get_home_directory(user=self.user_not_me)

doc_to_copy = Document2.objects.create(
name='new_doc', type='query-hive', owner=self.user_not_me, data={}, parent_directory=user_not_me_home_dir
)
# "user_not_me" can view document
assert doc_to_copy.can_read(self.user_not_me)
# "user" cannot view document
assert not doc_to_copy.can_read(self.user)
# "user_not_me" shares with user
doc_to_copy.share(self.user_not_me, users=[self.user])
# "user" can view document
assert doc_to_copy.can_read(self.user)
# The doc resides in the home directory of "user_not_me"
assert doc_to_copy.parent_directory == user_not_me_home_dir

# "user" makes a copy of the doc owned by "user_not_me" which resides in the home directory of "user_not_me"
copied_doc = doc_to_copy.copy(name=doc_to_copy.name + '-copy', owner=self.user)

# The copy should be located in the home folder of "user"
user_home_dir = Document2.objects.get_home_directory(user=self.user)
assert user_home_dir != user_not_me_home_dir
assert copied_doc.parent_directory == user_home_dir

def test_copy_of_doc_in_shared_folder(self):
user_not_me_home_dir = Document2.objects.get_home_directory(user=self.user_not_me)
user_not_me_shared_dir = Directory.objects.create(name='test_dir', owner=self.user_not_me, parent_directory=user_not_me_home_dir)

doc_to_copy = Document2.objects.create(
name='new_doc', type='query-hive', owner=self.user_not_me, data={}, parent_directory=user_not_me_shared_dir
)
# "user_not_me" can view document
assert doc_to_copy.can_read(self.user_not_me)
# "user" cannot view document
assert not doc_to_copy.can_read(self.user)
# "user_not_me" shares the parent directory with user
user_not_me_shared_dir.share(self.user_not_me, users=[self.user])
# "user" can view document
assert doc_to_copy.can_read(self.user)
# The doc resides in the shared directory of "user_not_me"
assert doc_to_copy.parent_directory == user_not_me_shared_dir

# "user" makes a copy of the doc owned by "user_not_me" which resides in the shared directory of "user_not_me"
copied_doc = doc_to_copy.copy(name=doc_to_copy.name + '-copy', owner=self.user)

# The copy should be located in the shared directory of "user_not_me"
assert copied_doc.parent_directory == user_not_me_shared_dir

def test_directory_move(self):
source_dir = Directory.objects.create(name='test_mv', owner=self.user, parent_directory=self.home_dir)
target_dir = Directory.objects.create(name='test_mv_dst', owner=self.user, parent_directory=self.home_dir)
Expand Down

0 comments on commit a2c3090

Please sign in to comment.