如何使用API​​ /服务帐户删除没有所有权的Google文档 [英] How to delete a google docs without ownership using an API/Services account

查看:136
本文介绍了如何使用API​​ /服务帐户删除没有所有权的Google文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



到目前为止我尝试过的方法




  • 尝试使用服务帐户删除文档(尝试,失败)

  • 试图将文档删除为admin admin(尝试失败)
  • >


在我的最后一次尝试中,我试图按照此线程中提出的解决方案

使用Google Drive API从不同所有者处删除文件


  1. 以服务帐户登录(服务帐户已获得域名范围的授权 https: //developers.google.com/drive/web/delegation )(成功)


  2. 模拟为文档的所有者。 (成功)


  3. 试图将所有者更改为管理员帐户。 (失败,此文件权限不足)

  4. 试图删除文档(失败,文件权限不足)
  5. b $ b

示例代码

 字符串serviceAccountEmail =xxxxxx -bpoaj0ekfgcort8tcqpqh661ceet9pqs@developer.gserviceaccount.com; 
var certificate = new X509Certificate2(@key.p12,notasecret,X509KeyStorageFlags.Exportable);
ServiceAccountCredential凭证=新的ServiceAccountCredential(新的ServiceAccountCredential.Initializer (serviceAccountEmail)
{
Scopes = Scopes,
User =user//<<<< - >我向用户填充以模仿
} .FromCertificate(certificate ));

//创建服务
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer =凭证,
ApplicationName =Drive API Sample,
});

UpdatePermission(service,d.DocId __c,permission_id,所有者); //< - 将管理帐户的权限更新为所有者

FilesResource.DeleteRequest request = service.Files.Delete(d.DocId__c);
String response = request.Execute(); //< - 在此处删除文档,是否需要使用管理员帐户再次登录?


解决方案

通过更改UpdatePermission方法使用TransferOwnership =真正;包含完整的代码片段

 私有异步System.Threading.Tasks.Task Run()
{
字符串ownerPermissionId =;
字符串ownerEmail =;
字符串adminEmail =abeer.qureshi@hidden.com;
String adminPermissionId =;


字符串serviceAccountEmail =895523393387-bpoaj0ekfgcort8tcqpqh661ceet9pqs@developer.gserviceaccount.com;
var certificate = new X509Certificate2(@key.p12,notasecret,X509KeyStorageFlags.Exportable);

//创建服务。
var service = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = Scopes
} .FromCertificate(certificate)),
ApplicationName =Drive API Sample,
});

//创建admin模拟服务
var adminService = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = new ServiceAccountCredential(
new ServiceAccountCredential .Initializer(serviceAccountEmail)
{
Scopes = Scopes,
User = adminEmail
} .FromCertificate(certificate)),
ApplicationName =Drive API Sample,
});

//这是由Visual Studio生成的Web引用对象
SforceService sfservice = SForceLogin.Login();
sfservice.Timeout = 60000;

QueryResult result = sfservice.query(选择Id,Name,DocId__c from G_Doc__c where PleaseDelete__c = true limit 200);

列表< String> toDelete =新列表< String>();

if(result.size> 0)
{
sObject [] docs = result.records;

foreach(sObject so in docs){
G_Doc__c d =(G_Doc__c)so;

尝试
{
IList< Permission> lstPermissions = RetrievePermissions(adminService,d.DocId__c);

if(lstPermissions == null)
{
toDelete.Add(d.Id);
继续;
}

foreach(权限p中的权限)
{
if(p.Role ==owner)
{
ownerEmail = p.EmailAddress;
ownerPermissionId = p.Id;
}
else if(p.EmailAddress == adminEmail)
{
adminPermissionId = p.Id;
}
}

//创建所有者模拟服务。
var impersonatedService = new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = Scopes,
User = ownerEmail
} .FromCertificate(certificate)),
ApplicationName =Drive API Sample,
});


UpdatePermission(adminService,impersonatedService,d.DocId__c,adminPermissionId,owner);

FilesResource.DeleteRequest请求= adminService.Files.Delete(d.DocId__c);
String response = request.Execute();
if(String.IsNullOrEmpty(response))
{
Console.Out.WriteLine(Deleted+ d.Name);
toDelete.Add(d.Id);
}
else
{
Console.Out.WriteLine(Error Deleting+ d.Name +:+ response);
}

catch(Exception ex){
if(ex.Message.Contains(File not found))
{
toDelete。加入(d.Id);
Console.Out.WriteLine(Error Deleting+ d.Name);
}
else
{
Console.Out.WriteLine(Error Deleting+ d.Name +:+ ex.Message);
}
}
}

DeleteResult [] dr = sfservice.delete(toDelete.ToArray());
}
}

// ...

///< summary>
///检索权限列表。
///< / summary>
///< param name =service>云端硬盘API服务实例< / param>
///< param name =fileId>要检索权限的文件的ID。< / param>
///<返回>权限列表。< / returns>
public static IList< Permission> RetrievePermissions(DriveService service,String fileId)
{
try
{
PermissionList permissions = service.Permissions.List(fileId).Execute();
返回permissions.Items;

catch(Exception e)
{
Console.WriteLine(发生错误:+ e.Message);
}
返回null;
}

///< summary>
///更新权限的角色。
///< / summary>
///< param name =service>云端硬盘API服务实例< / param>
///< param name =fileId>要更新权限的文件的ID< / param>
///< param name =permissionId>更新权限的ID< / param>
///< param name =newRole>值owner,writer或reader。< / param>
///< returns>更新的权限,如果发生API错误,则返回null< / returns>
public static Permission UpdatePermission(DriveService service,DriveService impersonatedService,String fileId,
String permissionId,String newRole)
{
try
{
//第一个从API中检索权限。
权限权限= service.Permissions.Get(fileId,permissionId).Execute();
permission.Role = newRole;

PermissionsResource.UpdateRequest request = impersonatedService.Permissions.Update(permission,fileId,permissionId);
request.TransferOwnership = true;
返回request.Execute();

catch(Exception e)
{
Console.WriteLine(发生错误:+ e.Message);
}
返回null;
}


I have failed in all my attempts to delete a document without the ownership.

What I have tried so far

  • Attempted to delete document using a services account (Tried, Failed)
  • Attempted to delete document as drive admin (Tried, Failed)

In my final attempt; I am trying to follow the solution suggested in this thread

Delete a file from different owner with Google Drive API

  1. Logged in as a services account (service account has been authorized with domain-wide delegation https://developers.google.com/drive/web/delegation) (Success)

  2. Impersonate as the owner of the document. (Success)

  3. Attempted to change owner to drive admin account. (Failed with Insufficient permissions for this file)

  4. Attempted to delete the document (Failed with Insufficient permissions for this file)

Sample Code"

String serviceAccountEmail = "xxxxxx-bpoaj0ekfgcort8tcqpqh661ceet9pqs@developer.gserviceaccount.com";
var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);            
ServiceAccountCredential credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail) 
{
    Scopes = Scopes,
    User = "user" //<<-- I populate this with the user to impersonate
}.FromCertificate(certificate));

// Create the service.
var service = new DriveService(new BaseClientService.Initializer()
{
    HttpClientInitializer = credential,
    ApplicationName = "Drive API Sample",
    });

UpdatePermission(service, d.DocId__c , permission_id, "owner"); //<-- updating the permissions of the admin account to owner

FilesResource.DeleteRequest request = service.Files.Delete(d.DocId__c);
String response = request.Execute(); //<-- deleting the doc here, do i need to login again using admin account?

解决方案

Issue was resolved by changing UpdatePermission method to use TransferOwnership = true; Full code snippet included

    private async System.Threading.Tasks.Task Run()
    {
        String ownerPermissionId = "";
        String ownerEmail = "";
        String adminEmail = "abeer.qureshi@hidden.com";
        String adminPermissionId = "";


        String serviceAccountEmail = "895523393387-bpoaj0ekfgcort8tcqpqh661ceet9pqs@developer.gserviceaccount.com";
        var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable);

        // Create the service.
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = Scopes
           }.FromCertificate(certificate)),
            ApplicationName = "Drive API Sample",
        });

        // Create admin impersonated service
        var adminService = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = new ServiceAccountCredential(
           new ServiceAccountCredential.Initializer(serviceAccountEmail)
           {
               Scopes = Scopes,
               User = adminEmail
           }.FromCertificate(certificate)),
            ApplicationName = "Drive API Sample",
        });

        // this is the web reference object generated by Visual Studio
        SforceService sfservice = SForceLogin.Login();
        sfservice.Timeout = 60000;

         QueryResult result = sfservice.query("select Id, Name, DocId__c from G_Doc__c where PleaseDelete__c = true limit 200");

        List<String> toDelete = new List<String>();

        if (result.size > 0) 
        {
            sObject[] docs = result.records;

            foreach (sObject so in docs){
                G_Doc__c d = (G_Doc__c)so;

                try
                {
                    IList<Permission> lstPermissions = RetrievePermissions(adminService, d.DocId__c);

                    if (lstPermissions == null)
                    {
                        toDelete.Add(d.Id);
                        continue;
                    }

                    foreach (Permission p in lstPermissions)
                    {
                        if (p.Role == "owner")
                        {
                           ownerEmail = p.EmailAddress;
                           ownerPermissionId = p.Id;
                        }
                        else if (p.EmailAddress == adminEmail)
                        {
                            adminPermissionId = p.Id;
                        }
                    }

                    // Create owner impersonated service.
                    var impersonatedService = new DriveService(new BaseClientService.Initializer()
                    {
                        HttpClientInitializer = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountEmail)
                    {
                        Scopes = Scopes,
                        User = ownerEmail
                    }.FromCertificate(certificate)),
                        ApplicationName = "Drive API Sample",
                    });


                    UpdatePermission(adminService, impersonatedService , d.DocId__c, adminPermissionId, "owner");

                    FilesResource.DeleteRequest request = adminService.Files.Delete(d.DocId__c);
                    String response = request.Execute();
                    if (String.IsNullOrEmpty(response))
                    {
                        Console.Out.WriteLine("Deleted " + d.Name);
                        toDelete.Add(d.Id);
                    }
                    else
                    {
                        Console.Out.WriteLine("Error Deleting " + d.Name + " : " + response);
                    }
                }
                catch (Exception ex) {
                    if (ex.Message.Contains("File not found"))
                    {
                        toDelete.Add(d.Id);
                        Console.Out.WriteLine("Error Deleting " + d.Name);
                    }
                    else
                    {
                        Console.Out.WriteLine("Error Deleting " + d.Name + " : " + ex.Message);
                    }
                }
            }

            DeleteResult[] dr = sfservice.delete(toDelete.ToArray());
        }
    }

    // ...

    /// <summary>
    /// Retrieve a list of permissions.
    /// </summary>
    /// <param name="service">Drive API service instance.</param>
    /// <param name="fileId">ID of the file to retrieve permissions for.</param>
    /// <returns>List of permissions.</returns>
    public static IList<Permission> RetrievePermissions(DriveService service, String fileId)
    {
        try
        {
            PermissionList permissions = service.Permissions.List(fileId).Execute();
            return permissions.Items;
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
        return null;
    }

    /// <summary>
    /// Update a permission's role.
    /// </summary>
    /// <param name="service">Drive API service instance.</param>
    /// <param name="fileId">ID of the file to update permission for.</param>
    /// <param name="permissionId">ID of the permission to update.</param>
    /// <param name="newRole">The value "owner", "writer" or "reader".</param>
    /// <returns>The updated permission, null is returned if an API error occurred</returns>
    public static Permission UpdatePermission(DriveService service, DriveService impersonatedService, String fileId,
        String permissionId, String newRole)
    {
        try
        {
            // First retrieve the permission from the API.
            Permission permission = service.Permissions.Get(fileId, permissionId).Execute();
            permission.Role = newRole;

            PermissionsResource.UpdateRequest request = impersonatedService.Permissions.Update(permission, fileId, permissionId);
            request.TransferOwnership = true;
            return request.Execute();
        }
        catch (Exception e)
        {
            Console.WriteLine("An error occurred: " + e.Message);
        }
        return null;
    }

这篇关于如何使用API​​ /服务帐户删除没有所有权的Google文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆