4
votes

When attempting to transfer ownership I get the following error:

"domain": "global",
"reason": "invalidSharingRequest",
"message": "Bad Request. User message: \"You can't change the owner of this item.\""

Here is my code:

use Google_Client; 
use Google_Service_Drive;
use Google_Service_Drive_DriveFile;
use Google_Service_Drive_Permission;

public function uploadDocument() {

 $FOLDER_ID = 'my_folder_ID_string';

 $client = new Google_Client();
 $client->setAuthConfig(base_path('service_account_credentials.json'));
 $client->setScopes(array('https://www.googleapis.com/auth/drive'));

 $service = new Google_Service_Drive($client);

 $fileMetadata = new Google_Service_Drive_DriveFile(array(
                                                     'name' => 'Test.pdf',
                                                     'parents' => [$FOLDER_ID]
                                                    ));

 $content = file_get_contents(public_path('tmp/Test.pdf'));

 $file = $service->files->create($fileMetadata, array(
                                                    'data' => $content,
                                                    'mimeType' => 'application/pdf',
                                                    'uploadType' => 'multipart',
                                                    'fields' => 'id'
                                                     ));

  // Transfer Ownership
  $newPermission = new Google_Service_Drive_Permission();
  $newPermission->setRole('owner');
  $newPermission->setType('user');
  $newPermission->setEmailAddress('[email protected]');
  $optParams = array('transferOwnership' => 'true');

  $service->permissions->create($file->id, $newPermission, $optParams);

}

The folder is successfully uploaded to Google Drive in the shared folder (owner is '[email protected]', service account is 'editor'), however the owner of the uploaded file is the service account and the editor is '[email protected]'.

1
Things to try: 1. add the new users as write access first then update it to owner 2. wait a bit after creating the file before attempting to change permissions.DaImTo
Thanks tried both methods but they didn't work.spaghetti_code

1 Answers

5
votes

You cannot change the owner of a file located on a shared drive

As per documentation:

Files within a shared drive are owned by the shared drive, not individual users.

Consequently, there is no need to "take away" the ownership from the service account.

You can make give users any other role, e.g. organizer which would allow the user to move the file out of the shared drive and thus become the owner of the file.\

UPDATE

If the files are uploaded by the service account to a shared folder on the user's Drive rather than to a shared Drive, the situation is different.

In specific:

  • For GSuite users the transfer of ownership outside of the domain is not allowed and will result in the error Ownership can only be transferred to another user in the same organization as the current owner..
  • A service account is not considered as a domain user and thus subjected to the same restrictions.
  • For consumer users the transfer of ownership from the service account to the user is allowed, but restricted: Only for documents of Google mimeType the owner can be changed.
  • Due to the above mentioned restrictions of transferring ownership from the service account to the user, it is better to avoid the problem by using impersonation.
  • Impersonation means that the a service account acts on behalf of a user (e.g. you) and when he uploads files to your Drive, it is equivalent to when you upload files yourself - no transfer of ownership is necessary, no explicit sharing of a folder with the service account is necessary.
  • To set-up impersonation you need to
    • Enable domain-wide delgation for the specific service account in your GCP console.

    • Authorize all the scopes the service account needs in your Admin console by going on Security > API Controls > Domain wide delegation.

    • Modify your code by adding the line

      $client->setSubject($EmailOfUserToImpersonate);

  • Mind that unfortunately domain-wide delegation is only possible for domains - that is GSuite accounts.
  • For consumer (gmail) accounts it is not possible to transfer ownership for a non-Google mimeType from the service account to the user.
  • As a workaround the user can make a copy of the file uploaded by the service account - subsequently the service account can delete the original file.