Hadar Ben David
Hadar Ben David

Reputation: 214

Google drive API V3, trying to change the ownership of files other than docs sheets and slides

I am using google API for google drive, V3 with C# dot net. When trying to change the ownership from my service account to a 'regular' drive account (so it is within the same domain) of files other than docs, sheets and slides (like .zip or even .pdf) I get an error saying that:

Error: Bad Request. User message: "You can't yet change the owner of this item. (We're working on it.).

I guess this has something to do with the fact that docs, sheets and slides are not taken into account in the storage quota. (1) Does this have a workaround? (Trying to change the file name to .doc before uploading it causes auto file conversion of the file and it is useless after that). (2) Does this also happen on a paid account? (3) Is Google team really 'working on it' as it states in the error message?

UPDATE: This is the code I am using:

    public string UploadFileToDrive(string FilePath, string ParentID)
    {
        try
        {
            Google.Apis.Drive.v3.Data.File body = new Google.Apis.Drive.v3.Data.File();
            string fileNameNoPath = System.IO.Path.GetFileName(FilePath);
            body.Name = "NewFile.ASC"; // some file names such as zip are not acceptable by google drive api
            //body.MimeType = GoogleDriveMimeTypes.GetGenericMimeTypeString();
            if (ParentID != null)
            {
                body.Parents = new List<string>();
                body.Parents.Add(ParentID);
            }


            byte[] byteArray = System.IO.File.ReadAllBytes(FilePath);
            System.IO.MemoryStream Ustream = new System.IO.MemoryStream(byteArray);

            var requestU = _CurrentDriveService.Files.Create(body, Ustream, "");
            requestU.Upload();
            var uploadedFileID = requestU.ResponseBody.Id;

            body.Name = fileNameNoPath;
            //body.MimeType = GoogleDriveMimeTypes.GetGenericMimeTypeString();
            FilesResource.CopyRequest cr = new FilesResource.CopyRequest(_CurrentDriveService, body, uploadedFileID);
            var newFile = cr.Execute();
            var NewFileNameID = newFile.Id;

            DeleteFileFromDrive(uploadedFileID);



            {
                Permission p = new Permission();
                p.Role = "reader";
                p.Type = "anyone";
                PermissionsResource.CreateRequest cc = new PermissionsResource.CreateRequest(_CurrentDriveService, p, NewFileNameID);
                cc.Execute();
            }


            // you can comment out the next block if using Auth client
            // 
            {
                // make main account the owner in order to take its size quota in main account not google service.
                Permission p = new Permission();
                p.Role = "owner";
                p.Type = "user";
                p.EmailAddress = "[email protected]";


                PermissionsResource.CreateRequest cc = new PermissionsResource.CreateRequest(_CurrentDriveService, p, NewFileNameID);
                cc.TransferOwnership = true; // acknowledge transfer of ownership - must be set to "true" in order for role to change to "owner"
                cc.Execute();
            }





            return NewFileNameID;

        }
        catch (Exception e)
        {
            System.Diagnostics.Debug.WriteLine(e.Message);
            return "";
        }



    }

With this code I can upload all files, change permissions for sharing, but I can't change ownership back to the google drive account.

Upvotes: 4

Views: 2718

Answers (1)

Hadar Ben David
Hadar Ben David

Reputation: 214

I finally found the answer. I need to impersonate to another user.

    var initializer = new ServiceAccountCredential.Initializer("[email protected]")
    {
        Scopes = scope,
        User = "emailToImpersonate@domain"
    };

    var credential = new ServiceAccountCredential(initializer.FromPrivateKey("-----BEGIN PRIVATE KEY-----\n-----END PRIVATE KEY-----\n"));

    var driveService = new DriveService(new BaseClientService.Initializer()
    {
        HttpClientInitializer = credential,
        ApplicationName = ApplicationName
    });

Also, make sure you give the google service domain wide delegation as shown here: https://developers.google.com/drive/v2/web/delegation and let up to 10 minutes for the change to take effect.

This is the workaround I have been searching for.

Upvotes: 1

Related Questions