Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File.setOwner() returns "Action not allowed" when Transferring ownership to an Editor

I have a google script that is used to generate a document from data stored inside of a google spreadsheet. After the document is generated, I am trying to change the owner to a different gmail account but I keep getting the following error:

[15-09-23 09:55:09:480 PDT] File.setOwner([[email protected]]) [1.03 seconds]

[15-09-23 09:55:09:566 PDT] Execution failed: Action not allowed (line 82, file "Helpers") [5.401 seconds total runtime]

I am trying to understand why I can't change the owner using Google App Script, but I can manually through Google Drive.


Details:

Bob ([email protected]) has shared a directory on his Drive with Alice ([email protected]). Inside the shared directory is a spreadsheet that is used to generate invoices from the content of the spreadsheet. Alice uses the spreadsheet (she has edit permissions) and invokes the "Generate > Invoice" menu action on the spreadsheet to create the invoice. Since she invoked the function, the file is created with Alice as the owner, but Bob wants to be the owner of all invoices. Bob has tried to set the owner of the document using Google App Script right after the document is created but it returns the error documented above.


Spreadsheet contents:

 |     A      |     B     |
1| First Name | Last Name |
2| John       | Doe       |

Google App Script:

/**
 * Adds a menu-item to allow the generation of documents
 *
 * @param {Object} e The event parameter for a simple onOpen trigger.
 */
function onOpen(e) {
  var menuitems = [];
  menuitems.push({
    name: "Invoice",
    functionName: "createInvoice"
  });
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  ss.addMenu("Generate", menuitems);
}


/**
 * This function reads data from cells A2:A3 to dynamically generate a document
 *
 */
function createInvoice() {
  var this_folder = cwd();
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
  var content = sheet.getRange("A2:A3").getValues()[0].join(" ");

  // Create a file with the given content
  var file = DriveApp.createFile("Invoice", content);

  // Add the file to the shared folder
  this_folder.addFile(file);

  // Remove the file from the user's root directory
  DriveApp.getRootFolder().removeFile(file);

  // Log the current owner of the document
  Logger.log(file.getOwner().getName());

  // Change the owner of the document from the active user to Bob. 
  file.setOwner("[email protected]");
}


/**
 * This is a helper function used to get the directory of the active spreadsheet.
 *
 */
function cwd() {
  var this_file = DriveApp.getFileById(SpreadsheetApp.getActive().getId());
  return this_file.getParents().next();
}

Steps to Reproduce:

  1. From a gmail account, share a folder with another gmail account.
  2. Create the Spreadsheet in the shared folder with the main gmail account:
  3. Add the Google App Script to the spreadsheet (AFTER changeing the setOwner line to the appropriate email address).
  4. Grant write access to the other gmail account.
  5. Login and load the document from the other gmail account.
  6. Invoke the script (Generate > Invoice). The first time you do this it will ask for permissions.
  7. The script should error out with the following error:

Action not allowed.

  1. If you open the Script and review the logs after you invoke the script it will show that the other gmail account owns the document and should be able to change it.

Additional Information:

  1. If I remove the "file.setOwner()" method, the file is created and I can manually set change the owner through the web interface.
  2. Using the script and setup, I have dynamically created folders and been able to change the owner using Google App Script. This problem only appears to effect the setOwner() method on Files.
like image 263
chad h. Avatar asked Sep 23 '15 17:09

chad h.


2 Answers

From the question (emphasis mine)

Alice uses the spreadsheet (she has edit permissions) and invokes the "Generate > Invoice" menu action on the spreadsheet to create the invoice. Since she invoked the function, the file is created with Alice as the owner, but Bob wants to be the owner of all invoices. Bob has tried to set the owner of the document using Google App Script right after the document is created but it returns the error documented above.

"Bob" can't transfer the ownership of the files because he is not the owner. The easier way is to ask "Alice", the actual file owner, to transfer the file ownership.

To prevent this problem, instead of using a custom menu "Bob" could create a web application with Google Apps Script setting it be be executed as him.

Another alternative for G Suite accounts is to create a service account with domain-wide delegation of authority to impersonate "Alice" to do the transfer of the ownership of the files. For details see the Peter Herman's answer to Transfer ownership of a file to another user in Google Apps Script

like image 61
Rubén Avatar answered Oct 06 '22 16:10

Rubén


This error likely happens when the file is placed inside the Team Drive folder of Google Drive.

like image 20
Amit Agarwal Avatar answered Oct 06 '22 17:10

Amit Agarwal