共用檔案、資料夾和雲端硬碟

每個 Google 雲端硬碟檔案、資料夾和共用雲端硬碟都有相關聯的 permissions 資源。每個資源都會識別特定 type (usergroupdomainanyone) 和 role (ownerorganizerfileOrganizerwritercommenterreader) 的權限。舉例來說,檔案可能會授予特定使用者 (type=user) 唯讀存取權 (role=reader),而另一項權限則會授予特定群組 (type=group) 成員在檔案中新增註解的權限 (role=commenter)。

如需角色的完整清單,以及各角色允許的作業,請參閱「角色和權限」。

雲端硬碟資源共用情境

共用情境分為五種:

  1. 如要分享「我的雲端硬碟」中的檔案,使用者必須具備 role=writerrole=owner

    • 如果檔案的 writersCanShare 布林值設為 false,使用者必須具備 role=owner

    • 如果具有 role=writer 的使用者擁有受限於到期日和時間的臨時存取權,就無法共用檔案。詳情請參閱「設定到期日以限制檔案存取權」。

  2. 如要共用「我的雲端硬碟」中的資料夾,使用者必須擁有 role=writerrole=owner

    • 如果檔案的 writersCanShare 布林值設為 false,使用者必須具備權限較高的 role=owner

    • role=writer 不允許在「我的雲端硬碟」資料夾中設定暫時存取權 (受到期日與時間限制)。詳情請參閱「設定檔案存取權到期日」。

  3. 如要分享共用雲端硬碟中的檔案,使用者必須具備 role=writerrole=fileOrganizerrole=organizer 權限。

    • writersCanShare 設定不適用於共用雲端硬碟中的項目。系統會將其視為一律設為 true
  4. 如要共用共用雲端硬碟中的資料夾,使用者必須具備 role=organizer

    • 如果共用雲端硬碟的 sharingFoldersRequiresOrganizerPermission 限制設為 false,擁有 role=fileOrganizer 的使用者就能在該共用雲端硬碟中分享資料夾。
  5. 如要管理共用雲端硬碟成員資格,使用者必須具備 role=organizer。只有使用者和群組可以成為共用雲端硬碟的成員。

設定檔案存取期限來限制檔案存取

與他人合作處理機密專案時,您可能會希望在一段時間後,限制他們存取雲端硬碟中特定檔案的權限。您可以為「我的雲端硬碟」中的檔案設定到期日,藉此限制或移除檔案存取權。

如要設定到期日,請按照下列步驟操作:

expirationTime 欄位會使用 RFC 3339 日期時間表示權限到期時間。到期時間有下列限制:

  • 只能對使用者和群組權限設定。
  • 時間必須是未來的時間。
  • 時間不得超過一年。

如要進一步瞭解到期日,請參閱下列文章:

權限傳播

資料夾的權限清單會向下傳播,所有子檔案和資料夾都會繼承父項的權限。每當權限或階層發生變更時,系統都會透過所有巢狀資料夾遞迴傳播。舉例來說,如果檔案位於某個資料夾中,而該資料夾隨後移至另一個資料夾,則新資料夾的權限會套用至檔案。如果新資料夾授予檔案使用者新的角色 (例如「作者」),則會覆寫舊角色。

相反地,如果檔案從資料夾繼承 role=writer,並移至提供「讀者」角色的其他資料夾,則檔案現在會繼承 role=reader

無法從共用雲端硬碟中的檔案或資料夾移除沿用權限。相反地,這些權限必須在沿用權限的直接或間接父項上調整。你可以從「我的雲端硬碟」或「與我共用」中的項目移除沿用權限。

反之,您可以在「我的雲端硬碟」中,針對檔案或資料夾覆寫繼承的權限。因此,如果檔案從「我的雲端硬碟」資料夾繼承 role=writer,您可以為檔案設定 role=reader,降低其權限層級。

功能

permissions 資源最終不會決定目前使用者是否能對檔案或資料夾執行動作。相反地,files 資源包含布林值 capabilities 欄位的集合,用於指出是否可以在檔案或資料夾上執行動作。Google 雲端硬碟 API 會根據與檔案或資料夾相關聯的目前使用者權限資源,設定這些欄位。

舉例來說,當 Alex 登入您的應用程式並嘗試共用檔案時,系統會檢查 Alex 的角色是否具有該檔案的權限。如果角色允許他們共用檔案,則與檔案相關的 capabilities (例如 canShare) 會根據角色填入。如果 Alex 想分享檔案,您的應用程式會檢查 capabilities,確保 canShare 設為 true

如需擷取檔案 capabilities 的範例,請參閱「驗證使用者權限」。

建立權限

建立權限時,必須填入下列兩個欄位:

  • typetype 會指出權限的範圍 (usergroupdomainanyone)。含有 type=user 的權限會套用至特定使用者,而含有 type=domain 的權限會套用至特定網域中的所有使用者。

  • rolerole 欄位會標示 type 可執行的作業。舉例來說,具有 type=userrole=reader 的權限會授予特定使用者對檔案或資料夾的唯讀存取權。或者,如果權限包含 type=domainrole=commenter,網域中的所有使用者都能為檔案加註。如需角色的完整清單,以及各角色允許的作業,請參閱「角色與權限」。

建立 type=usertype=group 的權限時,您必須提供 emailAddress,將特定使用者或群組與權限連結。

type=domain 中建立權限時,您必須提供 domain,將特定網域與權限連結。

如要建立權限,請按照下列步驟操作:

  1. 使用 create() 方法,並搭配相關檔案或資料夾的 fileId 路徑參數。
  2. 在要求主體中,指定 typerole
  3. 如果是 type=usertype=group,請提供 emailAddress。如果是 type=domain,請提供 domain

顯示範例

以下程式碼範例說明如何建立權限。回應會傳回 Permission 資源的例項,包括已指派的 permissionId

要求

POST https://www.googleapis.com/drive/v3/files/FILE_ID/permissions
{
  "requests": [
    {
        "type": "user",
        "role": "commenter",
        "emailAddress": "alex@altostrat.com"
    }
  ]
}

回應

{
    "kind": "drive#permission",
    "id": "PERMISSION_ID",
    "type": "user",
    "role": "commenter"
}

使用目標對象

目標對象是一群使用者 (例如部門或團隊),可當做使用者的建議共用對象。您可以鼓勵使用者與特定或部分目標對象 (而非整個機構) 共用項目。目標對象可協助你提升資料的安全性和隱私權,並讓使用者更輕鬆地妥善分享內容。詳情請參閱「關於指定目標對象」。

如何使用目標對象:

  1. 在 Google 管理控制台中,依序點選「選單」圖示 >「目錄」 >「目標對象」

    前往「目標對象」

    您必須使用具備超級管理員權限的帳戶登入,才能執行這項工作。

  2. 在「目標對象」清單中,按一下目標對象名稱。如要建立目標對象,請參閱「建立目標對象」一文

  3. 從目標對象網址複製專屬 ID:https://admin.google.com/ac/targetaudiences/ID

  4. 使用 type=domain 建立權限,並將 domain 欄位設為 ID.audience.googledomains.com

如要查看使用者與目標對象的互動方式,請參閱「連結分享的使用者體驗」。

擷取檔案、資料夾或共用雲端硬碟的所有權限

請使用 permissions 資源的 list() 方法,擷取檔案、資料夾或共用雲端硬碟的所有權限。

顯示範例

以下程式碼範例說明如何取得所有權限。回應會傳回權限清單。

要求

GET https://www.googleapis.com/drive/v3/files/FILE_ID/permissions

回應

{
  "kind": "drive#permissionList",
  "permissions": [
    {
      "id": "PERMISSION_ID",
      "type": "user",
      "kind": "drive#permission",
      "role": "commenter"
    }
  ]
}

驗證使用者權限

應用程式開啟檔案時,應檢查檔案的功能,並算繪 UI 以反映目前使用者的權限。舉例來說,如果使用者在檔案上沒有 canComment 功能,則應在 UI 中停用註解功能。

如要進一步瞭解 capabilities,請參閱「功能」一節。

如要檢查功能,請在 files 資源上呼叫 get() 方法,並將 fileId 路徑參數和 fields 參數設為 capabilities 欄位。如要進一步瞭解如何使用 fields 參數傳回欄位,請參閱「傳回檔案的特定欄位」一文。

顯示範例

以下程式碼範例說明如何驗證使用者權限。回應會傳回使用者對檔案擁有的功能清單。每項功能都對應到使用者可採取的精細動作。部分欄位只會填入共用雲端硬碟中的項目。

要求

GET https://www.googleapis.com/drive/v3/files/FILE_ID?fields=capabilities

回應

{
  "capabilities": {
    "canAcceptOwnership": false,
    "canAddChildren": false,
    "canAddMyDriveParent": false,
    "canChangeCopyRequiresWriterPermission": true,
    "canChangeSecurityUpdateEnabled": false,
    "canComment": true,
    "canCopy": true,
    "canDelete": true,
    "canDownload": true,
    "canEdit": true,
    "canListChildren": false,
    "canModifyContent": true,
    "canModifyContentRestriction": true,
    "canModifyLabels": true,
    "canMoveChildrenWithinDrive": false,
    "canMoveItemOutOfDrive": true,
    "canMoveItemWithinDrive": true,
    "canReadLabels": true,
    "canReadRevisions": true,
    "canRemoveChildren": false,
    "canRemoveMyDriveParent": true,
    "canRename": true,
    "canShare": true,
    "canTrash": true,
    "canUntrash": true
  }
}

判斷共用雲端硬碟檔案和資料夾的角色來源

如要變更檔案或資料夾的角色,您必須知道角色的來源。對於共用雲端硬碟,角色來源可以根據共用雲端硬碟的成員資格、資料夾上的角色,或檔案上的角色。

如要判斷共用雲端硬碟或該雲端硬碟內的項目的角色來源,請在 permissions 資源上呼叫 get() 方法,並使用 fileIdpermissionId 路徑參數,以及設為 permissionDetails 欄位的 fields 參數。

如要尋找 permissionId,請在 permissions 資源上使用 list() 方法,並搭配 fileId 路徑參數。如要擷取 list 要求的 permissionDetails 欄位,請將 fields 參數設為 permissions/permissionDetails

這個欄位會列舉使用者、群組或網域的所有沿用和直接檔案權限。

顯示範例

以下程式碼範例說明如何判斷角色來源。回應會傳回 permissions 資源的 permissionDetailsinheritedFrom 欄位會提供權限繼承的項目 ID。

要求

GET https://www.googleapis.com/drive/v3/files/FILE_ID/permissions/PERMISSION_ID?fields=permissionDetails&supportsAllDrives=true

回應

{
  "permissionDetails": [
    {
      "permissionType": "member",
      "role": "commenter",
      "inheritedFrom": "INHERITED_FROM_ID",
      "inherited": true
    },
    {
      "permissionType": "file",
      "role": "writer",
      "inherited": false
    }
  ]
}

變更權限

如要變更檔案或資料夾的權限,可以變更指派的角色:

  1. permissions 資源上呼叫 update() 方法,並將 permissionId 路徑參數設為要變更的權限,將 fileId 路徑參數設為相關聯的檔案、資料夾或共用雲端硬碟。如要尋找 permissionId,請在 permissions 資源上使用 list() 方法,並搭配 fileId 路徑參數。

  2. 在要求中指出新的 role

即使使用者或群組已是共用雲端硬碟的成員,您還是可以授予他們個別檔案或資料夾的權限。舉例來說,Alex 是共用雲端硬碟的role=commenter 成員。不過,您的應用程式可以將共用雲端硬碟中的檔案授予 Alex role=writer。在這種情況下,由於新角色比透過會籍授予的角色權限更寬鬆,因此新權限會成為檔案或資料夾的有效角色

顯示範例

以下程式碼範例說明如何將檔案或資料夾的權限從「註解者」變更為「作者」。回應會傳回 permissions 資源的例項。

要求

PATCH https://www.googleapis.com/drive/v3/files/FILE_ID/permissions/PERMISSION_ID
{
  "requests": [
    {
        "role": "writer"
    }
  ]
}

回應

{
  "kind": "drive#permission",
  "id": "PERMISSION_ID",
  "type": "user",
  "role": "writer"
}

列出並解決待處理的存取權提案

存取權提案是要求者向核准者提出的提案,要求核准者授予收件者 Google 雲端硬碟項目的存取權。

核准者可以查看並處理所有未解決的雲端硬碟檔案存取權提案。也就是說,您可以透過程式輔助方式查詢存取權提案,然後解決這些提案,加快審核程序。並允許核准者匯總查看提案。

雲端硬碟 API 提供 accessproposals 資源,方便您查看及解決待處理的存取提案。accessproposals 資源的方法適用於檔案、資料夾、共用雲端硬碟中的檔案,但適用於共用雲端硬碟。

以下是存取權提案專屬的條款:

  • 提出要求者:發起 Drive 項目存取權提案的使用者。
  • 收件者:如果存取權提案獲得核准,則是指收到檔案額外權限的使用者。收件者通常與要求者相同,但不一定如此。
  • 核准者:負責核准 (或拒絕) 存取權提案的使用者。這通常是因為他們是文件的擁有者,或是有權分享文件。

列出待處理的存取提案

如要列出雲端硬碟項目上所有待處理的存取提案,請在 accessproposals 資源上呼叫 list() 方法,並加入 fileId 路徑參數。

只有檔案核准者才能列出檔案中的待處理提案。核准者是指擁有檔案 can_approve_access_proposals 功能的使用者。如果要求者不是核准者,系統會傳回空白清單。如要進一步瞭解 capabilities,請參閱「功能」一節。

回應主體包含 AccessProposal 物件,代表檔案中未解決的存取提案清單。

AccessProposal 物件包含每個提案的相關資訊,例如要求者、收件者,以及要求者新增的訊息。它還包含 AccessProposalRoleAndView 物件,可將要求者的建議 roleview 分組。由於 role 是重複欄位,因此每個提案都可能有多次重複。舉例來說,提案可能包含 role=readerview=publishedAccessProposalRoleAndView 物件,以及另一個只包含 role=writer 值的 AccessProposalRoleAndView 物件。詳情請參閱「Views」。

傳遞下列查詢參數,即可自訂存取提案的分頁或篩選條件:

  • pageToken:從先前 list 呼叫收到的頁面權杖。提供這個符記即可擷取後續網頁。

  • pageSize:每頁返回的存取建議數量上限。

解決待處理的存取權提案

如要解決 Drive 項目上所有待處理的存取提案,請在 accessproposals 資源上呼叫 resolve() 方法,並加入 fileIdproposalId 路徑參數。

resolve() 方法包含 action 查詢參數,用於表示要對提案採取的動作。Action 物件會追蹤提案的狀態變更,讓我們知道提案是否已接受或拒絕。

resolve() 方法也包含選用的 roleview 查詢參數。系統僅支援 writercommenterreader 這三種角色。如果未指定角色,則預設為 reader。另外,您可以使用 send_notification 這個選用的查詢參數,在提案獲得核准或拒絕時,向提出要求者傳送電子郵件通知。

list() 方法一樣,解決提案的使用者必須具備檔案的 can_approve_access_proposals 功能。如要進一步瞭解 capabilities,請參閱「功能」一節。

我們會使用「Drive 資源共用情境」一節所列的相同模式來解決提案。如果同一位使用者有多項提案,但角色不同,則適用下列規定:

  • 如果一個提案已接受,另一個提案已拒絕,則會將已接受的角色套用至 Drive 項目。
  • 如果兩個提案同時通過,系統會套用具有較高權限的提案 (例如 role=writerrole=reader)。其他存取權提案會從項目中移除。

將提案傳送至 resolve() 方法後,分享動作就會完成。AccessProposal 不再透過 list() 方法傳回。提案通過後,使用者必須使用 permissions 集合,更新檔案或資料夾的權限。詳情請參閱「變更權限」一節。

撤銷檔案或資料夾的存取權

如要撤銷檔案或資料夾的存取權,請在 permissions 資源上呼叫 delete() 方法,並設定 fileIdpermissionId 路徑參數,以便刪除權限。

對於「我的雲端硬碟」中的項目,您可以刪除繼承的權限。刪除沿用權限會撤銷對項目和子項 (如有) 的存取權。

共用雲端硬碟中的項目無法撤銷沿用權限。請改為更新或撤銷上層檔案或資料夾的權限。

delete() 方法也可用來刪除直接套用至共用雲端硬碟檔案或資料夾的權限。

顯示範例

下列程式碼範例說明如何刪除 permissionId 來撤銷存取權。如果成功,回應主體會留白。如要確認權限已移除,請在 permissions 資源上使用 list() 方法,並搭配 fileId 路徑參數。

要求

DELETE https://www.googleapis.com/drive/v3/files/FILE_ID/permissions/PERMISSION_ID

將檔案擁有權轉移至同一機構中的其他 Google Workspace 帳戶

您可以將「我的雲端硬碟」中檔案的擁有權,從一個 Google Workspace 帳戶轉移至同一機構中的其他帳戶。擁有共用雲端硬碟的機構,也擁有其中的檔案。因此,共用雲端硬碟中的檔案和資料夾不支援擁有權轉移功能。共用雲端硬碟的管理員可以將項目從該共用雲端硬碟移至自己的「我的雲端硬碟」,並將擁有權轉移給對方。

如要轉移「我的雲端硬碟」中檔案的擁有權,請執行下列任一操作:

  • 建立檔案權限,授予特定使用者 (type=user) 擁有者存取權 (role=owner)。

  • 使用 role=owner 更新現有檔案的權限,並將擁有權轉移給指定使用者 (transferOwnership=true)。

將檔案擁有權從一個消費者帳戶轉移到另一個帳戶

檔案擁有權可在消費者帳戶之間轉移。不過,在擁有者明確同意轉移作業之前,雲端硬碟不會在兩個個人帳戶之間轉移檔案擁有權。如要將檔案擁有權從一個消費者帳戶轉移至另一個帳戶,請按照下列步驟操作:

  1. 目前的擁有者可以建立或更新潛在擁有者的檔案權限,以便啟動擁有權轉移程序。權限必須包含以下設定:role=writertype=userpendingOwner=true。如果目前的擁有者為潛在擁有者建立權限,系統會傳送電子郵件通知給潛在擁有者,指出對方被要求接管檔案的擁有權。

  2. 潛在擁有者可以建立或更新檔案權限,接受擁有權轉移要求。權限必須包含下列設定:role=ownertransferOwnership=true。如果潛在擁有者建立新的權限,系統會傳送電子郵件通知給先前的擁有者,指出擁有權已轉移。

轉移檔案後,先前的擁有者角色會降級為 writer

透過批次要求變更多項權限

強烈建議您使用批次要求來修改多個權限。

以下是使用用戶端程式庫執行批次權限修改作業的範例。

Java

drive/snippets/drive_v3/src/main/java/ShareFile.java
import com.google.api.client.googleapis.batch.BatchRequest;
import com.google.api.client.googleapis.batch.json.JsonBatchCallback;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.Permission;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/* Class to demonstrate use-case of modify permissions. */
public class ShareFile {

  /**
   * Batch permission modification.
   * realFileId file Id.
   * realUser User Id.
   * realDomain Domain of the user ID.
   *
   * @return list of modified permissions if successful, {@code null} otherwise.
   * @throws IOException if service account credentials file not found.
   */
  public static List<String> shareFile(String realFileId, String realUser, String realDomain)
      throws IOException {
        /* Load pre-authorized user credentials from the environment.
         TODO(developer) - See https://developers.google.com/identity for
         guides on implementing OAuth2 for your application.application*/
    GoogleCredentials credentials = GoogleCredentials.getApplicationDefault()
        .createScoped(Arrays.asList(DriveScopes.DRIVE_FILE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    Drive service = new Drive.Builder(new NetHttpTransport(),
        GsonFactory.getDefaultInstance(),
        requestInitializer)
        .setApplicationName("Drive samples")
        .build();

    final List<String> ids = new ArrayList<String>();


    JsonBatchCallback<Permission> callback = new JsonBatchCallback<Permission>() {
      @Override
      public void onFailure(GoogleJsonError e,
                            HttpHeaders responseHeaders)
          throws IOException {
        // Handle error
        System.err.println(e.getMessage());
      }

      @Override
      public void onSuccess(Permission permission,
                            HttpHeaders responseHeaders)
          throws IOException {
        System.out.println("Permission ID: " + permission.getId());

        ids.add(permission.getId());

      }
    };
    BatchRequest batch = service.batch();
    Permission userPermission = new Permission()
        .setType("user")
        .setRole("writer");

    userPermission.setEmailAddress(realUser);
    try {
      service.permissions().create(realFileId, userPermission)
          .setFields("id")
          .queue(batch, callback);

      Permission domainPermission = new Permission()
          .setType("domain")
          .setRole("reader");

      domainPermission.setDomain(realDomain);

      service.permissions().create(realFileId, domainPermission)
          .setFields("id")
          .queue(batch, callback);

      batch.execute();

      return ids;
    } catch (GoogleJsonResponseException e) {
      // TODO(developer) - handle error appropriately
      System.err.println("Unable to modify permission: " + e.getDetails());
      throw e;
    }
  }
}

Python

drive/snippets/drive-v3/file_snippet/share_file.py
import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def share_file(real_file_id, real_user, real_domain):
  """Batch permission modification.
  Args:
      real_file_id: file Id
      real_user: User ID
      real_domain: Domain of the user ID
  Prints modified permissions

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # create drive api client
    service = build("drive", "v3", credentials=creds)
    ids = []
    file_id = real_file_id

    def callback(request_id, response, exception):
      if exception:
        # Handle error
        print(exception)
      else:
        print(f"Request_Id: {request_id}")
        print(f'Permission Id: {response.get("id")}')
        ids.append(response.get("id"))

    # pylint: disable=maybe-no-member
    batch = service.new_batch_http_request(callback=callback)
    user_permission = {
        "type": "user",
        "role": "writer",
        "emailAddress": "user@example.com",
    }
    batch.add(
        service.permissions().create(
            fileId=file_id,
            body=user_permission,
            fields="id",
        )
    )
    domain_permission = {
        "type": "domain",
        "role": "reader",
        "domain": "example.com",
    }
    domain_permission["domain"] = real_domain
    batch.add(
        service.permissions().create(
            fileId=file_id,
            body=domain_permission,
            fields="id",
        )
    )
    batch.execute()

  except HttpError as error:
    print(f"An error occurred: {error}")
    ids = None

  return ids


if __name__ == "__main__":
  share_file(
      real_file_id="1dUiRSoAQKkM3a4nTPeNQWgiuau1KdQ_l",
      real_user="gduser1@workspacesamples.dev",
      real_domain="workspacesamples.dev",
  )

Node.js

drive/snippets/drive_v3/file_snippets/share_file.js
/**
 * Batch permission modification
 * @param{string} fileId file ID
 * @param{string} targetUserEmail username
 * @param{string} targetDomainName domain
 * @return{list} permission id
 * */
async function shareFile(fileId, targetUserEmail, targetDomainName) {
  const {GoogleAuth} = require('google-auth-library');
  const {google} = require('googleapis');

  // Get credentials and build service
  // TODO (developer) - Use appropriate auth mechanism for your app
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const service = google.drive({version: 'v3', auth});
  const permissionIds = [];

  const permissions = [
    {
      type: 'user',
      role: 'writer',
      emailAddress: targetUserEmail, // 'user@partner.com',
    },
    {
      type: 'domain',
      role: 'writer',
      domain: targetDomainName, // 'example.com',
    },
  ];
  // Note: Client library does not currently support HTTP batch
  // requests. When possible, use batched requests when inserting
  // multiple permissions on the same item. For this sample,
  // permissions are inserted serially.
  for (const permission of permissions) {
    try {
      const result = await service.permissions.create({
        resource: permission,
        fileId: fileId,
        fields: 'id',
      });
      permissionIds.push(result.data.id);
      console.log(`Inserted permission id: ${result.data.id}`);
    } catch (err) {
      // TODO(developer): Handle failed permissions
      console.error(err);
    }
  }
  return permissionIds;
}

PHP

drive/snippets/drive_v3/src/DriveShareFile.php
use Google\Client;
use Google\Service\Drive;
function shareFile()
{
    try {
        $client = new Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Drive::DRIVE);
        $driveService = new Drive($client);
        $realFileId = readline("Enter File Id: ");
        $realUser = readline("Enter user email address: ");
        $realDomain = readline("Enter domain name: ");
        $ids = array();
            $fileId = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ';
            $fileId = $realFileId;
            $driveService->getClient()->setUseBatch(true);
            try {
                $batch = $driveService->createBatch();

                $userPermission = new Drive\Permission(array(
                    'type' => 'user',
                    'role' => 'writer',
                    'emailAddress' => 'user@example.com'
                ));
                $userPermission['emailAddress'] = $realUser;
                $request = $driveService->permissions->create(
                    $fileId, $userPermission, array('fields' => 'id'));
                $batch->add($request, 'user');
                $domainPermission = new Drive\Permission(array(
                    'type' => 'domain',
                    'role' => 'reader',
                    'domain' => 'example.com'
                ));
                $userPermission['domain'] = $realDomain;
                $request = $driveService->permissions->create(
                    $fileId, $domainPermission, array('fields' => 'id'));
                $batch->add($request, 'domain');
                $results = $batch->execute();

                foreach ($results as $result) {
                    if ($result instanceof Google_Service_Exception) {
                        // Handle error
                        printf($result);
                    } else {
                        printf("Permission ID: %s\n", $result->id);
                        array_push($ids, $result->id);
                    }
                }
            } finally {
                $driveService->getClient()->setUseBatch(false);
            }
            return $ids;
    } catch(Exception $e) {
        echo "Error Message: ".$e;
    }

}

.NET

drive/snippets/drive_v3/DriveV3Snippets/ShareFile.cs
using Google.Apis.Auth.OAuth2;
using Google.Apis.Drive.v3;
using Google.Apis.Drive.v3.Data;
using Google.Apis.Requests;
using Google.Apis.Services;

namespace DriveV3Snippets
{
    // Class to demonstrate use-case of Drive modify permissions.
    public class ShareFile
    {
        /// <summary>
        /// Batch permission modification.
        /// </summary>
        /// <param name="realFileId">File id.</param>
        /// <param name="realUser">User id.</param>
        /// <param name="realDomain">Domain id.</param>
        /// <returns>list of modified permissions, null otherwise.</returns>
        public static IList<String> DriveShareFile(string realFileId, string realUser, string realDomain)
        {
            try
            {
                /* Load pre-authorized user credentials from the environment.
                 TODO(developer) - See https://developers.google.com/identity for
                 guides on implementing OAuth2 for your application. */
                GoogleCredential credential = GoogleCredential.GetApplicationDefault()
                    .CreateScoped(DriveService.Scope.Drive);

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

                var ids = new List<String>();
                var batch = new BatchRequest(service);
                BatchRequest.OnResponse<Permission> callback = delegate(
                    Permission permission,
                    RequestError error,
                    int index,
                    HttpResponseMessage message)
                {
                    if (error != null)
                    {
                        // Handle error
                        Console.WriteLine(error.Message);
                    }
                    else
                    {
                        Console.WriteLine("Permission ID: " + permission.Id);
                    }
                };
                Permission userPermission = new Permission()
                {
                    Type = "user",
                    Role = "writer",
                    EmailAddress = realUser
                };

                var request = service.Permissions.Create(userPermission, realFileId);
                request.Fields = "id";
                batch.Queue(request, callback);

                Permission domainPermission = new Permission()
                {
                    Type = "domain",
                    Role = "reader",
                    Domain = realDomain
                };
                request = service.Permissions.Create(domainPermission, realFileId);
                request.Fields = "id";
                batch.Queue(request, callback);
                var task = batch.ExecuteAsync();
                task.Wait();
                return ids;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}