Google Drive API / SDK TransferOwnership

I am trying to transfer ownership of a specific file to another user.

General code

foreach (Permission permission in RetrievePermissions(service(), file.Id))
        {
            if (permission.Role == EnumClass.PERMISSIONROLE.OWNER.ToText())
            {
                //Downgrade Owner Writer
                UpdatePermission(service(), file.Id, permission.Id, EnumClass.PERMISSIONROLE.WRITER);
                //Create New Writer
                InsertPermission(service(), file.Id, ownerMail, EnumClass.PERMISSIONROLE.WRITER);

                foreach (Permission thisPermission in RetrievePermissions(service(), file.Id))
                {   //Update Writer to Owner
                    if (thisPermission.Name == "Person X")
                    {
                        //Set Person X as new Owner
                        UpdatePermission(service(), file.Id, thisPermission.Id, EnumClass.PERMISSIONROLE.OWNER);
                    }
                }
            }
        }

      

Update permission method

public static Permission UpdatePermission(DriveService service, String fileId, String permissionId, EnumClass.PERMISSIONROLE ROLE)
    {
        try
        {
            // First retrieve the permission from the API.
            Permission permission = service.Permissions.Get(fileId, permissionId).Execute();
            permission.Role = ROLE.ToText();

            //if new Role is Owner, Downgrad current Owner
            if (ROLE == EnumClass.PERMISSIONROLE.OWNER)
            {
                var myPermission = service.Permissions.Update(permission, fileId, permissionId);
                myPermission.TransferOwnership = true;

                foreach (Permission per in RetrievePermissions(service, fileId))
                {
                    if (per.Role == EnumClass.PERMISSIONROLE.OWNER.ToText())
                    {
                        per.Role = EnumClass.PERMISSIONROLE.WRITER.ToText();
                    }
                }
            }
            return service.Permissions.Update(permission, fileId, permissionId).Execute();
        }

        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
        return null;

      

Insert permission method

 public static Permission InsertPermission(DriveService service, String fileId, String userMail, EnumClass.PERMISSIONROLE Role)
    {
        Permission newPermission = new Permission();
        newPermission.Name = userMail;
        newPermission.Value = userMail;
        newPermission.Type = EnumClass.PERMISSIONTYPE.USER.ToText();
        newPermission.Role = Role.ToText();

        try
        {
            return service.Permissions.Insert(newPermission, fileId).Execute();
        }
        catch (Exception InsertError)
        {
            Console.WriteLine("Error inserting permission for " + userMail + Environment.NewLine + "Error on Insert: " + InsertError.Message);
        }
        return null;
    }

      

Mistake

Google.Apis.Requests.RequestError Insufficient permissions for this file [403] Errors [Message [Insufficient permissions for this file] Location [-] Reason [Denied] Domain [global]]

I am currently using ServiceAccount.
All help is appreciated!

+2


source to share


2 answers


Have you tried using impersonation?



var initializer = new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
    Scopes = new[] { DriveService.Scope.Drive },
    User = "user@yourdomain.com"
};

      

+2


source


The best way to transfer ownership is

  • Allow domain delegation to service account

  • Perform user impersonation when initializing the disk service as shown below:



*

 using (var credentialJSON =new FileStream(_settings.CertificatePath,FileMode.Open, FileAccess.Read))
            {
                var credentialParameters =
                    NewtonsoftJsonSerializer.Instance.Deserialize<JsonCredentialParameters>(credentialJSON);

                credential = new ServiceAccountCredential(
                    new ServiceAccountCredential.Initializer(credentialParameters.ClientEmail)
                    {
                        Scopes = scopes,
                        User = ownerEmailAddress, //put in the actual user email address
                    }.FromPrivateKey(credentialParameters.PrivateKey));
            }

      

0


source







All Articles