17

OK, I've looked everywhere for the answer for this and don't seem to be able to find it.

We are trying to get our Google Drive organised so that the right people get access to the right things without a lot of explicit sharing. We have a top-level folder called "Company" with sub-folders for "Admin", "Finance", "HR", "Engineering" and so on. The sub-folders have more restrictive permissions than the top-level one.

We've now got more or less everything in the right place, and mostly this works. The problem is where individual files or folders have their own permissions - they then don't seem to inherit the permissions from their folders. How do we reset the permissions for everything in each part of the hierarchy so they are the same as the parent folder?

On Windows Server or Mac OS X there is a clear distinction between "inherited" and "explicit" permissions for an item, and it is easy to remove the "explicit" permissions for all the items in a hierarchy. Where is this for GD?

0

5 Answers 5

3

I installed Vidar’s script and works very well for files, but wouldn't reset permissions on folders. So, I changed a little bit the code to make the folders also inherite the permissions from their upper folder.

Two important disclaimers:

  1. I don't know if the original intention was to leave folders unchanged. Or even if it worked well for everybody but me, and this solutions was unnecesary. It worked for me.
  2. This is the first script I do, so it is very likely that it is not very efficient and may content some errors. Please feel free to correct it and improve it.

I only changed the doResetPermissions function, but I paste all the code for simplicity reasons.

var selectedFolder;
var dialog;

function doGet() {
  var app = UiApp.createApplication();
  var heading = app.createHTML("<h1>Folders for</h1>");
  app.add(heading);
  var allFoldersIterator = DriveApp.getFolders();
  var text = app.createTextArea().setName("text").setId("output");
  app.add(text);
  var tree = app.createTree();
  var rootFolder = DriveApp.getRootFolder();
  var treeRoot = app.createTreeItem(rootFolder.getName()).setId(rootFolder.getId());
  var handler = app.createServerHandler("folderSelected");
  tree.addItem(treeRoot);
  tree.addSelectionHandler(handler);
  treeRoot.setState(true);
  createBranch(rootFolder, treeRoot, app);
  app.add(tree);
  var selectedFolderIdBox = app.createTextBox().setName("selectedFolderIdBox").setId("selectedFolderIdBox");
  app.add(selectedFolderIdBox);
  return app;
}

function createBranch(folder, branch, app) {
  var children = folder.getFolders();
  while (children.hasNext()) {
    child = children.next();
    Logger.log("Folder id: " + child.getId());
    var subBranch = app.createTreeItem(child.getName()).setId(child.getId());
    branch.addItem(subBranch);
    createBranch(child, subBranch, app);
  }
}

function folderSelected(eventInfo) {
  var app = UiApp.getActiveApplication();
  var parameter = eventInfo.parameter;
  Logger.log("Selected " + eventInfo.parameter.selected);
  selectedFolder = DriveApp.getFolderById(eventInfo.parameter.selected);
  var selectedFolderIdBox = app.getElementById("selectedFolderIdBox");
  selectedFolderIdBox.setValue(eventInfo.parameter.selected);
  var okHandler = app.createServerHandler("okResetPermissions");
  okHandler.addCallbackElement(selectedFolderIdBox);
  dialog = app.createDialogBox(true, true);
  var panel = app.createFlowPanel();
  dialog.add(panel);
  dialog.setId("confirmationDialog");
  dialog.setPopupPosition(100, 100).setSize(500, 500);
  panel.add(app.createLabel("Do you want to reset permissions for all files found in folder " + selectedFolder.getName() + " and its subfolders?\n (Click outside of the dialog box to cancel)"));
  panel.add(app.createButton("Do it!", okHandler));
  dialog.show();
  return app;
}

function okResetPermissions(eventInfo) {
  var selectedFolderId = eventInfo.parameter.selectedFolderIdBox;
  var selectedFolder = DriveApp.getFolderById(selectedFolderId);
  Logger.log("Resetting permissions on " + selectedFolder.getName());
  var app = UiApp.getActiveApplication();
  app.getElementById("confirmationDialog").hide();
  Logger.log("Confirmation dialog hidden");
  var progressIndicator = app.createDialogBox(false, true);
  progressIndicator.setId("progressIndicator");
  progressIndicator.setPopupPosition(100, 100).setSize(500, 500);
  var label = app.createLabel("Working ...");
  progressIndicator.add(label);
  progressIndicator.show();
  doResetPermissions(selectedFolder, function() {
    var app = UiApp.getActiveApplication();
    var progressIndicator = app.getElementById("progressIndicator");
    progressIndicator.hide();
    return app;
  });
  return app;
}

function doResetPermissions(selectedFolder, callback) {
  Logger.log("Resetting permissions on folder " + selectedFolder.getName());

  var sharingAccess = selectedFolder.getSharingAccess();
  var sharingPermission = selectedFolder.getSharingPermission();

  var viewersfolder = selectedFolder.getViewers();
  Logger.log("Number of Viewers in folder: " + selectedFolder.getName() + " = " + viewersfolder.length);
  for (var i = 0; i < viewersfolder.length; i++) {
    Logger.log("      Removing viewer " + viewersfolder[i].getEmail());
    selectedFolder.removeViewer(viewersfolder[i]);
  }

  var editorsfolder = selectedFolder.getEditors();

  Logger.log("Number of Editors in folder: " + selectedFolder.getName() + " = " + editorsfolder.length);

  for (var i = 0; i < editorsfolder.length; i++) {
    Logger.log("      Removing editor " + editorsfolder[i].getEmail());
    selectedFolder.removeEditor(editorsfolder[i]);
  }

  var files = selectedFolder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    Logger.log("   Resetting permissions on file " + file.getName());
    file.setSharing(sharingAccess, sharingPermission);

    var viewers = file.getViewers();
    Logger.log("Number of Viewers in file: " + file.getName() + " = " + viewers.length);
    for (var i = 0; i < viewers.length; i++) {
      Logger.log("      Removing viewer " + viewers[i].getEmail());
      file.removeViewer(viewers[i]);
    }

    var editors = file.getEditors();

    Logger.log("Number of editors in file: " + file.getName() + " = " + editors.length);

    for (var i = 0; i < editors.length; i++) {
      Logger.log("      Removing editor " + editors[i].getEmail());
      file.removeEditor(editors[i]);
    }
  }

  var children = selectedFolder.getFolders();
  while (children.hasNext()) {
    var child = children.next();
    doResetPermissions(child);
  }

  if (callback) {
    callback();
  }
}
2
  • 1
    This is nice, except it deletes the non-google-ized files (like uploaded PDFs and DOCX files).
    – user683
    Dec 29, 2015 at 4:43
  • Well that just will not work for me then @user683. Where in the script does it "delete" files? That is so dangerous! This script is supposed to set permissions, not delete files!
    – Arvo Bowen
    Mar 26, 2018 at 1:16
3

If I need to reset folder permissions, I rename the folder (Finance → Finance_1), make new folder with the old name (Finance), and "move" all sub-folders to the new folder.

With this move, you reset all permissions for subfolders.

1
  • 1
    Did not work for me. The newly created folder had the proper inherited permissions, but the subfolders retained their out-of-sync permissions after being moved.
    – mmseng
    Oct 8, 2020 at 21:54
2

I have created a Google Apps Scripts webapp that should be close to what you want.

IMPORTANT! Before running this on any of your folders, make sure you test it on another account. Although the script seems to be working as intended, I cannot make any guarantee that it will not mess up your permissions. So go through the script carefully, check with the documentation for Google Apps Scripts, and test it thoroughly before running on any production data.

The script's UI is very rudimentary, so don't except anything fancy.

var selectedFolder;
var dialog;

function doGet() {
  var app = UiApp.createApplication();
  var heading = app.createHTML("<h1>Folders for</h1>");
  app.add(heading);
  var allFoldersIterator = DriveApp.getFolders();
  var text = app.createTextArea().setName("text").setId("output");
  app.add(text);
  var tree = app.createTree();
  var rootFolder = DriveApp.getRootFolder();
  var treeRoot = app.createTreeItem(rootFolder.getName()).setId(rootFolder.getId());
  var handler = app.createServerHandler("folderSelected");
  tree.addItem(treeRoot);
  tree.addSelectionHandler(handler);
  treeRoot.setState(true);
  createBranch(rootFolder, treeRoot, app);
  app.add(tree);
  var selectedFolderIdBox = app.createTextBox().setName("selectedFolderIdBox").setId("selectedFolderIdBox");
  app.add(selectedFolderIdBox);
  return app;
}

function createBranch(folder, branch, app) {
  var children = folder.getFolders();
  while (children.hasNext()) {
    child = children.next();
    Logger.log("Folder id: " + child.getId());
    var subBranch = app.createTreeItem(child.getName()).setId(child.getId());
    branch.addItem(subBranch);
    createBranch(child, subBranch, app);
  }
}

function folderSelected(eventInfo) {
  var app = UiApp.getActiveApplication();
  var parameter = eventInfo.parameter;
  Logger.log("Selected " + eventInfo.parameter.selected);
  selectedFolder = DriveApp.getFolderById(eventInfo.parameter.selected);
  var selectedFolderIdBox = app.getElementById("selectedFolderIdBox");
  selectedFolderIdBox.setValue(eventInfo.parameter.selected);
  var okHandler = app.createServerHandler("okResetPermissions");
  okHandler.addCallbackElement(selectedFolderIdBox);
  dialog = app.createDialogBox(true, true);
  var panel = app.createFlowPanel();
  dialog.add(panel);
  dialog.setId("confirmationDialog");
  dialog.setPopupPosition(100, 100).setSize(500, 500);
  panel.add(app.createLabel("Do you want to reset permissions for all files found in folder " + selectedFolder.getName() + " and its subfolders?\n (Click outside of the dialog box to cancel)"));
  panel.add(app.createButton("Do it!", okHandler));
  dialog.show();
  return app;
}

function okResetPermissions(eventInfo) {
  var selectedFolderId = eventInfo.parameter.selectedFolderIdBox;
  var selectedFolder = DriveApp.getFolderById(selectedFolderId);
  Logger.log("Resetting permissions on " + selectedFolder.getName());
  var app = UiApp.getActiveApplication();
  app.getElementById("confirmationDialog").hide();
  Logger.log("Confirmation dialog hidden");
  var progressIndicator = app.createDialogBox(false, true);
  progressIndicator.setId("progressIndicator");
  progressIndicator.setPopupPosition(100, 100).setSize(500, 500);
  var label = app.createLabel("Working ...");
  progressIndicator.add(label);
  progressIndicator.show();
  doResetPermissions(selectedFolder, function() {
    var app = UiApp.getActiveApplication();
    var progressIndicator = app.getElementById("progressIndicator");
    progressIndicator.hide();
    return app;
  });
  return app;
}

function doResetPermissions(selectedFolder, callback) {
  Logger.log("Resetting permissions on folder " + selectedFolder.getName());
  var sharingAccess = selectedFolder.getSharingAccess();
  var sharingPermission = selectedFolder.getSharingPermission();
  var files = selectedFolder.getFiles();
  while (files.hasNext()) {
    var file = files.next();
    Logger.log("   Resetting permissions on file " + file.getName());
    file.setSharing(sharingAccess, sharingPermission);
    var viewers = file.getViewers();
    for (var i = 0; i < viewers.length; i++) {
      Logger.log("      Removing viewer " + viewers[i].getEmail());
      file.removeViewer(viewers[i]);
    }
    var editors = file.getEditors();
    for (var i = 0; i < editors.length; i++) {
      Logger.log("      Removing editor " + editors[i].getEmail());
      file.removeEditor(editors[i]);
    }
  }
  var children = selectedFolder.getFolders();
  while (children.hasNext()) {
    var child = children.next();
    doResetPermissions(child);
  }
  if (callback) {
    callback();
  }
}

To install this script, go to your Google Drive and click New → Google Apps Script. Paste in the code, and Publish → Distribute as web-app.
Set the script to Run as the logged-in user (or similar, my Google Drive is not in English).

When invoking the app, you will be shown the folder hierarchy of your Google Drive. Clicking on a folder will display an ugly-looking popup, where you can choose to execute a permission reset script for the folder and its subfolders (the function doResetPermissions in the code).
This function iterates through the folder and its subfolders. For each file it finds, it executes file.setSharing with values from the parent folder. It also calls file.removeViewer for all viewers registered, and file.removeEditor for all registered editors.

Check the documentation for removeViewer and removeEditor to be sure they do what you want.

Note that executing the script may take some time (depending on the size of your folder structure), and no feedback is given while it's working, except in the script runner logs (View → Logs).

0
0

I found out that the best way was to use rclone copy to recreate the parent folder with all of it's files, while changing permissions into whatever default sharing settings you chose.

So if you have, say a team drive with a bunch of directories, just move everything into a new folder such as bad_permissions. Then create a new remote in rclone for that drive and use rclone copy gdrive:bad_permissions gdrive:fixed_permissions. Since the copy happens server-side, you avoid having to download/upload.

WARNING: I checked the copied folder with a file comparison tool afterwards to make sure everything had transferred properly and rclone actually had missed quite a large amount of files without displaying any errors.

-2

http://gappstips.com/docs-tips/view/98/protect-your-google-drive-folders-by-setting-permissions

according to that link it seems like you need to make sure the files are set to the default permissions then they should inherit from the folder.

edit: ctrl+a selects all files in the folder then you can change who they are shared with all at once.

2
  • 2
    I think the OP wants to know how you can reset permissions to default for all documents at once. Aug 9, 2014 at 12:40
  • 2
    We have many folders. How to do this recursively for ALL files in them?
    – Kromster
    Aug 11, 2014 at 8:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.