1
votes

I just started using Google Drive API and turns out I can't migrate ownership of the created file. I uploaded a file to drive from a service account, then gave myself the "writer" permission and tried to update myself to an owner, as it is written in api docs.

media = MediaFileUpload(filename, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
file = driveService.files().create(media_body=media, fields='id').execute()
access = driveService.permissions().create(
    fileId = file['id'],
    body = {'type': 'user', 'role': 'writer', 'emailAddress': my_email},
    fields = 'id'
).execute()
update = driveService.permissions().update(fileId=file.get('id'), 
                                         permissionId=access.get('id'), 
                                         transferOwnership=True,
                                         body = {'role': 'owner', 'emailAddress': my_email }).execute()
--------------------------------------------------------------------------
HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/file_id/permissions/permission_id?transferOwnership=true&alt=json returned "The resource body includes fields which are not directly writable.">

Update: issue was fixed by removing an "emailAddress" parameter, but then I got new error:

HttpError: <HttpError 403 when requesting https://www.googleapis.com/drive/v3/files/fileId/permissions/permissionId?transferOwnership=true&alt=json returned "The user does not have sufficient permissions for this file.">

Another update: I reauploaded credetials file and it fixed the second error.

1
Great! You should accept an answer to your question. Check what-to-do-when-someone-answers.Aerials

1 Answers

0
votes

According to the docs the body's writable arguments are only "role" and "expirationTime" but you are trying to assign email address to an existing permission again, hence the error "The resource body includes fields which are not directly writable."

The permission created in access already has an email associated to it, you can alter the "role" and "expirationTime" only. Also the body of the request in access does not specify a "role", it specifies a "writer" property, so that's a typo.


Update:

When you insert a file into Drive, that file has as the owner, the owner of the Drive where it was uploaded to. So I'm assuming:

  1. The account impersonated by the service account (the initial owner of the uploaded file) is not the same email address as the one you are creating a permission for in your access object.
  2. In the body of the request to create a permission of type user, you need to pass the id or value optional parameters to identify the user. (You are correctly passing "id" but "emailAddress" is redundant) Try in API explorer
  3. The first time you updated the permission you likely already transfered the ownership to the user of the "writer" permission who should now be the owner of the file, hence the impersonated account doesn't have sufficient permissions for that file.

You can quickly check the file permissions in the API explorer making a request to Files.get and see the owner(s) of the file, along with all other properties.