4

Is it possible to hand over the owner permission to the other user and change the former owner to a viewer using apps script?

Transferring the owner permission to another user and being a viewer

I'm trying to make a script that hands over the owner to another user and changes the former owner to a viewer or prohibits the former owner from editing the Google Spreadsheet. The problem is the script is run by the former owner and the script cannot remove the edit permission of the former owner.

What I have tried

I tried setViewer(), sheet.protect(), and contentRestictions.readOnly but all of them was not a viable solution

  1. removeEditors() and setViewer()

setViewer() method to an editors has no effects, and after applying removeEditors() to the former owner(after changing the owner, of course) the script cannot execute setViewer() since it does not have permission anymore.

  1. sheet.protect()

the method gives the permission to edit the protected range for the owner and the user who runs the script. not eligible.

  1. contentRestrictions.readOnly

the restriction can be unlocked by editors. not feasible.

  • Code for contentRestrictions:

    function setReadOnly() { var ss = SpreadsheetApp.getActive(); var supervisor = 'xxxxxxxx@gmail.com'; file = DriveApp.getFileById(ss.getId()); try { Drive.Files.update({ 'writersCanShare': false, 'copyRequiresWriterPermission': true, 'contentRestrictions': [{ 'readOnly': true }] }, ss.getId()); file.setSharing(DriveApp.Access.ANYONE_WITH_LINK, DriveApp.Permission.NONE); file.setOwner(supervisor); } catch (e) { console.log(e); } }

I recently found the contentRestrictions.readOnly has been implemented to Google Drive API. While I thought it would be a great way to restrict the editors from modifying the file content, I realized the users who are editors can "UNLOCK" the file with a click even it was locked by the owner.

I don't understand the use of this property if the restriction can be resolved by editors. The explanation in the docs says that we can use this field to prevent modifications to the title, uploading a new revision, and addition of comments. However, editors easily unlock the files, and the viewers cannot modify the file anyway.

nkink
  • 120
  • 1
  • 10
  • Can I ask you about the detail of your situation? 1. About `I'm trying to make a script that hands over the owner to other user and changes the former owner to a viewer or prohibit the former owner from editing the Google Spreadsheet.`, I cannot understand about "owner" and "other user". For example, "owner" is you? 2. In your situation, when you want to use a script, who does the script run? Who is the owner of the script? 3. You want to transfer the owner of your Spreadsheet to other user and you want to keep the permission as the reader which is not the writer. Is my understanding correct? – Tanaike Feb 17 '21 at 01:35
  • @Tanaike Correct. So, the script is acting like a submit or approval process. When the owner finishes the work and press the submit menu, the script make him/her a viewer and transfer the ownership to the supervisor. The former owner cannot modify the document any more but still should be able to read the docs for the finalized data. Surely, it can be done by manual job but I want to make it work with apps script. – nkink Feb 17 '21 at 02:29
  • Thank you for replying. I have to apologize for my poor English skill. I cannot understand about ` When the owner finishes the work and press the submit menu, the script make him/her a viewer and transfer the ownership to the supervisor.`. And, from your replying, I couldn't understand about the relationship between the owner and the user for the Spreadsheet and the script. But I would like to try to understand about it. When I could correctly understand about it, I would like to think of the solution and workaround. I deeply apologize that I cannot understand about your question soon. – Tanaike Feb 17 '21 at 02:35
  • A: a boss, B: file owner. B complete the file and give it to A, the boss. A doesn't want B modify the file after giving it to him/her. So B sets the owner to A, and change B's permission to reader only. – nkink Feb 17 '21 at 02:52
  • Thank you for replying and adding more information. From your additional information, I proposed a sample script as an answer. Could you please confirm it? But there is an important point. In this script, after the owner of Spreadsheet is changed, you cannot edit the Spreadsheet and the script. So please be careful this. And, if I misunderstood your situation and question, I apologize. – Tanaike Feb 17 '21 at 03:40

2 Answers2

2

I believe your current situation and your goal as follows.

  • You have a Google Spreadsheet and a script. You are the owner of them.
    • From your script, the script is the container-bound script of the Spreadsheet.
  • When you run the script, you want to transfer the owner of Spreadsheet to other user.
  • After the owner was transferred, you want to keep to have the permission for the Spreadsheet as the reader which is not the writer.

Modification points:

  • In this case, I thought that the methods of "Permissions: insert" and "Permissions: update" of Drive API (in this case, Drive API is used with Advanced Google services.) might be able to be used for achieving your goal.
  • The flow of my proposing script is as follows.
  1. Retrieve the permission ID for you.
    • In the current stage, you are the owner of the file.
  2. Transfer the owner of file (in your case, it's Spreadsheet.).
    • In the current stage, you are not the owner.3. Update your permission from writer to reader.
  3. Create a shortcut of the owner-transferred Spreadsheet to the root folder.
    • Because, when the owner is transferred, the file can be seen at the folder of "Shared with me".
    • If you are not required to create the shortcut, please remove this part.

This flow is reflected to a script, it becomes as follows.

Modified script:

Please copy and paste the following script to the script editor of the container-bound script of Google Spreadsheet. And, before you use this script, please enable Drive API at Advanced Google services.

function myFunction() {
  const email = "###"; // Please set the email. The owner of the file is transferred to this email.

  const fileId = SpreadsheetApp.getActive().getId();
  
  // 1. Retrieve the permission ID for you. In the current stage, you are the owner of the file.
  const permissionId = Drive.Permissions.list(fileId).items[0].id;

  // 2. Transfer the owner of file (in your case, it's Spreadsheet.). In the current stage, you are not the owner.
  Drive.Permissions.insert({role: "owner", type: "user", value: email}, fileId, {sendNotificationEmail: false, moveToNewOwnersRoot: true});

  // 3. Update your permission from `writer` to `reader`.
  Drive.Permissions.update({role: "reader"}, fileId, permissionId);

  // 4. Create a shortcut of the owner-transferred Spreadsheet to the root folder. Because, when the owner is transferred, the file can be seen at the folder of "Shared with me".
  Drive.Files.insert({mimeType: MimeType.SHORTCUT, shortcutDetails: {targetId: fileId}}, null);
}

Note:

  • When above script is run the owner of Spreadsheet is changed to email. And your permission becomes the reader. So in this case, you cannot see the script of Spreadsheet. Please be careful this.
  • In this case, after the owner of Spreadsheet is changed, you cannot edit the Spreadsheet and the script. So please be careful this.

References:

Tanaike
  • 181,128
  • 11
  • 97
  • 165
  • @nkink Thank you for replying and testing it. I'm glad your issue was resolved. I could correctly understand about your question by your cooperation. Thank you, too. – Tanaike Feb 17 '21 at 05:20
  • Sorry, today I tested it again and found it's not working as expected. I got `GoogleJsonResponseException: API call to drive.permissions.update failed with error: Insufficient permissions for this file` error at no3. changing permission from 'writer' to 'reader'. – nkink Feb 18 '21 at 10:06
  • if the file already has a wanna-be owner as a reader or a writer, the error is produced while changing the former owner(who became writer after setting new owner) to reader. – nkink Feb 18 '21 at 11:47
  • @nkink About your new question, I would like to support you. But unfortunately, I cannot understand about `if the file already has a wanna-be owner as a reader or a writer, the error is produced while changing the former owner(who became writer after setting new owner) to reader.`. I apologize for my poor English skill. – Tanaike Feb 18 '21 at 12:17
  • @nkink Before I think about your new question, can I confirm about my understanding of your question which is not your new question? In your question, I understood as follows. `When you run the script, you want to transfer the owner of Spreadsheet to other user. After the owner was transferred, you want to keep to have the permission for the Spreadsheet as the reader which is not the writer.` Is my understanding correct? – Tanaike Feb 18 '21 at 12:17
  • If the file has other users(readers or viewer), `Drive.Permissions.update(role: "reader"}, fileId, permissionId);` makes `Insufficient permissions` error. I don't understand the reason but solved the issue with this additional code. I updated the additional code to the original post. – nkink Feb 18 '21 at 13:36
  • @nkink Thank you for replying. I have to apologize for my poor English skill. I'm glad your new question was resolved. – Tanaike Feb 18 '21 at 23:38
  • Can you please check this question? https://stackoverflow.com/questions/66478838 I'm trying to create trigger and make it run by other users but always got failure sign. – nkink Mar 06 '21 at 12:31
  • @nkink About your new question, I will check it. And, when I could correctly understand about it and find the solution, I would like to answer it. And, when I have questions for your new question, I would like to comment them. But, if I couldn't understand about your new question, I apologize. – Tanaike Mar 06 '21 at 12:40
  • Thank you very much. I tried to use your code from https://github.com/tanaikech/CopyFolder#sample-script-2 but it did not work when it was executed by other users' permission. – nkink Mar 06 '21 at 22:01
  • @nkink Thank you for replying. I would like to support you. But the issue of your comment is new issue, and that is different from your question. So can you post it as new question by including the detail information? Because when your initial question is changed by comment, other users who see your question are confused. By posting it as new question, users including me can think of it. If you can cooperate to resolve your new issue, I'm glad. Can you cooperate to resolve your new question? – Tanaike Mar 07 '21 at 00:41
  • Yes, this is the new question. https://stackoverflow.com/questions/66478838 Thank you very much. – nkink Mar 07 '21 at 04:31
  • @nkink Thank you for replying. About your new question, when I could correctly understand about it and find the solution, I would like to answer it. I deeply apologize I cannot resolve your new question soon. This is due to my poor English skill. I deeply apologize for this again. – Tanaike Mar 07 '21 at 05:13
  • Thank you very much. I like your code for google apps script. I'm your big fan. – nkink Mar 07 '21 at 05:23
1

I tested my own file below, only me have access to the file.

Code:

function myFunction() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ssId = ss.getId();
  var file = DriveApp.getFileById(ssId);
  var owner = file.getOwner();

  var new_owner = 'new_owner@gmail.com';
  file.setOwner(new_owner);
  file.removeEditor(owner);    // After this line, you can't view/edit the file
  Logger.log(file.getOwner()); // Will fail
}

Things noted during testing:

  • Running removeEditor on yourself after setting another user as owner will restrict you from even viewing the file as per testing
  • Owner is immune with removeEditor (can't be removed by such)
  • Only the owner can set the ownership to other users

Please see a similar question that has an answer pointing to this, it will give you some insights regarding Google Apps Domain-Wide Delegation of Authority.

NightEye
  • 10,634
  • 2
  • 5
  • 24
  • Thank you but I need to maintain the viewer permission for the former owner as I mentioned at "removerEditor and setViewer". – nkink Feb 16 '21 at 22:08
  • To do that the answer of Ruben which uses a service account is a kind of solution for me from the link you gave. However I'm still looking for a way to do this simple job without a kind of superadmin authorities. – nkink Feb 16 '21 at 22:23