diff --git a/tavern/tomes/file_tree/main.eldritch b/tavern/tomes/file_tree/main.eldritch index 8b807f59d..0885f4dbc 100644 --- a/tavern/tomes/file_tree/main.eldritch +++ b/tavern/tomes/file_tree/main.eldritch @@ -1,33 +1,70 @@ block_list = ["/proc","/sys","/lib","/libx32","/lib32","/lib64","/boot","/srv","/usr","/snap","/run","/dev","/cores"] +usernfo = sys.get_user() +windows = sys.is_windows() -def file_list(path,tree): +def can_read(f): + """Return true if the user can read this dir/file + """ + # Bypass until windows perms are implemented + if windows: + return True + + PERM_READ = 4 + f_user = int(f["permissions"][-3]) # User byte + f_group = int(f["permissions"][-2]) # Group byte + + # Check world byte first so it hopefully is fast + if int(f["permissions"][-1]) & PERM_READ: + return True + + # Are we root? + root = usernfo["euid"]["uid"] == 0 + + # If the user isnt root and the user doesnt own the file, clear the user byte + if not root and f["owner"] not in (usernfo["euid"]["name"], usernfo["uid"]["name"]): + f_user = 0 + + # TODO: https://github.com/spellshift/realm/issues/570 + # Will NOT match any group other than primary until #570 is fixed + + # If the user isnt root and the group doesnt own the file, clear the group byte + if not root and f["group"] not in (str(usernfo["egid"]), str(usernfo["gid"])): + f_group = 0 + + if (f_group & PERM_READ) | (f_user & PERM_READ): + return True + return False + +def file_list(path,tree, depth=-1): tree="|\t"+tree + if depth == 0: + return files = file.list(path) for f in files: if path+f['file_name'] in block_list: - print("Skipping: "+path+f['file_name']+"\n") + print("Skipping: "+path+f['file_name']) continue if f['type'] == "Directory": - print(tree+"|---"+path+"/"+f['file_name']+"\n") - file_list(path+"/"+f['file_name'],tree) + print(tree+"|---"+f['file_name']+"/") + if can_read(f): + file_list(path+"/"+f['file_name'],tree, depth=depth-1) if f['type'] == "Link": - print(tree+"|---"+f['file_name']+"\n") + print(tree+"|---"+f['file_name']) if f['type'] == "File": - print(tree+"|---"+f['file_name']+"\n") + print(tree+"|---"+f['file_name']) -def main(path): +def main(path, depth=-1): tree="" + depth=int(depth) if file.is_dir(path): print(path+"\n") if path == "/": - print("It looks like you're trying to list every file on the system.\n") - print("This generates a lot of data so I'm going to exclude less helpful directories\n") - print("If you really really want everything including /proc and /sys specify \"//\"\n") - file_list(path,tree) + print("It looks like you're trying to list every file on the system.") + print("This generates a lot of data so I'm going to exclude less helpful directories") + print("If you really really want everything including /proc and /sys specify \"//\"") + file_list(path,tree, depth=depth) elif file.is_file(path): - print("Error: Invalid Path ("+path+")\n") + print("Error: Invalid Path ("+path+")") -main(input_params['path']) -print("\n") -print("\n") +main(input_params['path'], input_params["depth"]) \ No newline at end of file diff --git a/tavern/tomes/file_tree/metadata.yml b/tavern/tomes/file_tree/metadata.yml index 5e42bd14b..0ee0a4c70 100644 --- a/tavern/tomes/file_tree/metadata.yml +++ b/tavern/tomes/file_tree/metadata.yml @@ -8,3 +8,7 @@ paramdefs: type: string label: File path placeholder: "/etc/" +- name: depth + type: int + label: Recurse Depth + placeholder: "3, or -1 for infinite recursion"