Skip to content

Commit

Permalink
Merge pull request #114 from valeriupredoi/fix_auto_download_permissions
Browse files Browse the repository at this point in the history
Fix auto download permissions
  • Loading branch information
ledm authored Oct 30, 2023
2 parents a775ec0 + 4300bbd commit f0df659
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 6 deletions.
42 changes: 36 additions & 6 deletions bgcval2/download_from_mass.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from socket import gethostname
import shutil
import os
from pwd import getpwuid
import stat
from glob import glob
from re import findall
Expand Down Expand Up @@ -407,9 +408,20 @@ def download_from_mass(

paths = get_paths(config_user)
outputFold = folder([paths.ModelFolder_pref, jobID,] )
# make this folder group writeable.
st = os.stat(outputFold)
os.chmod(outputFold, st.st_mode | stat.S_IWGRP)

# Check permissions on the output folder
i_can_write_this = os.access(outputFold, os.W_OK)
if i_can_write_this:
# I created this folder and I own it.
# make this folder group writeable.
os.chmod(outputFold, st.st_mode | stat.S_IWGRP)
else:
# Someone else created it and they own it,
# so I can't change permissions.
uname = getpwuid(st.st_uid).pw_name
print('WARNING: someone else (', uname, ') owns this directory, so you may not be able to download files.')
print('WARNING: Ask them politely to run "chmod g+w ',outputFold,'"')

deleteBadLinksAndZeroSize(outputFold, jobID)

Expand Down Expand Up @@ -483,8 +495,25 @@ def download_from_mass(
if auto_download:
shared_file_path = os.path.join(paths.shared_mass_scripts, os.path.basename(download_script_path))
print('writing file in shared path', shared_file_path)
shutil.copy(download_script_path, shared_file_path)

# check destination permissions:
i_can_write_this = os.access(shared_file_path, os.W_OK)
if i_can_write_this:
# I created this file and I own it:
# make local copy group writable:
os.chmod(download_script_path, st.st_mode | stat.S_IWGRP)

# copy local to shared folder:
shutil.copy(download_script_path, shared_file_path)

# make shared copy group writable: (possibly overkill)
os.chmod(shared_file_path, st.st_mode | stat.S_IWGRP)
else:
# I don't have permission to edit this file. Someone else does:
uname = getpwuid(os.stat(shared_file_path).st_uid).pw_name
print('WARNING: someone else (', shared_file_path, ') owns this directory, so you may not be able to download files.')
print('WARNING: Ask them politely to run "chmod g+w ', shared_file_path,'"')

fixFilePaths(outputFold, jobID, debug=False,)
deleteBadLinksAndZeroSize(outputFold, jobID, debug=False,)

Expand Down Expand Up @@ -598,13 +627,14 @@ def deleteBadLinksAndZeroSize(outputFold, jobID, debug=True):
bashCommand1 = "find " + outputFold + "/. -size 0 -print -delete"
bashCommand2 = "find -L " + outputFold + "/. -type l -delete -print"

if debug: print("deleteBadLinksAndZeroSize:\t", bashCommand1)
bashCommand1 = bashCommand1.replace('//', '/')
bashCommand2 = bashCommand2.replace('//', '/')

print("deleteBadLinksAndZeroSize:\t", bashCommand1)
process1 = subprocess.Popen(bashCommand1.split(), stdout=subprocess.PIPE)
output1 = process1.communicate()[0]

if debug: print("deleteBadLinksAndZeroSize:\t", bashCommand2)

print("deleteBadLinksAndZeroSize:\t", bashCommand2)
process2 = subprocess.Popen(bashCommand2.split(), stdout=subprocess.PIPE)
output2 = process2.communicate()[0]

Expand Down
40 changes: 40 additions & 0 deletions tests/unit/test_download_from_mass_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os
import shutil
import stat

from bgcval2.download_from_mass import download_from_mass as dfm


def test_allowed_user():
user_home = os.path.expanduser('~')
output_folder = "bgcval2/local_test/BGC_data/u-xxx/"
run_dir = os.path.join(user_home, output_folder)
if not os.path.exists(run_dir):
os.makedirs(run_dir)
dfm(jobID="u-xxx",
doMoo=False,
auto_download=False,
config_user="defaults"
)
try:
assert os.stat(run_dir).st_mode == 16893
# when stat mode is 16877 (equivalent to chmod 877)
except AssertionError:
assert os.stat(run_dir).st_mode == 16877


def test_disallowed_user():
user_home = os.path.expanduser('~')
output_folder = "bgcval2/local_test/BGC_data/u-yyy/"
run_dir = os.path.join(user_home, output_folder)
if not os.path.exists(run_dir):
os.makedirs(run_dir)
st = os.stat(run_dir)
os.chmod(run_dir, False)
dfm(jobID="u-yyy",
doMoo=False,
auto_download=False,
config_user="defaults"
)
assert os.stat(run_dir).st_mode == 16384
shutil.rmtree(run_dir, ignore_errors=True)

0 comments on commit f0df659

Please sign in to comment.