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

所有 Google 雲端硬碟檔案、資料夾和共用雲端硬碟都建立關聯 權限資源。每項資源 識別特定 type (使用者、群組、網域、任何人) 的權限 和 role,例如「加註者」或「讀取器」舉例來說,一個檔案可能含有 將唯讀存取權授予特定使用者 (type=user) 的權限 (role=reader),另一項權限則是將特定群組的成員授予 (type=group) 可以在檔案 (role=commenter) 中新增註解。

如需完整的角色清單以及每個角色允許執行的作業,請參閱 角色與權限

共用雲端硬碟資源的使用情境

共用方式分為五種:

  1. 如要共用「我的雲端硬碟」中的檔案,使用者必須具備 role=writer 裝置的權限 或 role=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) 日期時間 ,直接在 Google Cloud 控制台實際操作。到期時間具有以下限制:

  • 並且只能針對使用者和群組權限設定。
  • 時間必須設為未來的時間。
  • 時間不得早於未來一年。

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

權限傳播

資料夾的權限清單向下傳播,以及所有子檔案與 資料夾會沿用上層資料夾的權限無論 階層有所變更,傳播至所有巢狀結構中,都會以遞迴方式發生 資料夾。舉例來說,如果檔案存在於某個資料夾中,而隨後移動了該資料夾, 新資料夾的權限則會套用至檔案。 如果新資料夾授予檔案使用者一個新角色 (例如「寫入者」),該資料來源 舊角色會覆寫舊角色

相反地,如果檔案繼承資料夾的 role=writer,且移至他處, 另一個開啟「讀取工具」功能的資料夾角色,檔案現在會沿用 role=reader

您無法移除共用雲端硬碟中檔案或資料夾的沿用權限。 你必須在 所屬的資料夾您可以將沿用的權限從以下項目中移除: 「我的雲端硬碟」或「與我共用」

反過來說,您也可以覆寫「我的」中檔案或資料夾沿用的權限 開車、因此,如果檔案沿用「My」的 role=writer 你可以前往雲端硬碟資料夾,將 role=reader 檔案縮小 權限等級。

功能

Permissions 資源不會 判斷目前使用者在檔案或資料夾執行操作的能力。 不過,Files 資源會包含一組 capabilities 布林值欄位,用來表示動作是否可 對檔案或資料夾所做的變更Google Drive API 會根據 與檔案或資料夾相關聯的目前使用者權限資源。

舉例來說,小李登入您的應用程式並嘗試分享檔案時,就是小李的角色 已檢查檔案的權限。如果角色允許共用檔案 已填入與檔案相關的 capabilities (例如 canShare) 而不是角色如果 Alex 想要分享檔案,應用程式會檢查 capabilities,確保 canShare 已設為 true

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

建立權限

建立權限時,必須提供以下兩個欄位:

  • typetype 識別權限範圍 (usergroupdomainanyone)。具備 type=user 的權限適用於特定使用者 擁有 type=domain 的權限適用於特定網域中的所有使用者。

  • rolerole 欄位 識別 type 可執行的作業。舉例來說 透過 type=userrole=reader 的權限可授予特定使用者 擁有檔案或資料夾的唯讀存取權。或是擁有「type=domain」的權限 和 role=commenter,允許網域中的所有使用者對檔案加註。適用對象 完整清單以及各角色所允許的操作 角色與權限

type=usertype=group 建立權限時,您還必須 提供 emailAddress 和 授予特定使用者或群組的權限

當您建立權限,其中 type=domain 時,您必須一併提供 可將 domain 連結至特定網域 授予的權限

如何建立權限:

  1. 使用 permissions.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"
}

使用目標對象

目標對像是指可自訂的使用者群組,例如部門或團隊 推薦使用者與他們共用項目您可以鼓勵使用者分享 目標對像是特定或有限的目標對象 並根據貴機構的使命 價值觀和目標進行調整目標對像功能可協助您 也能讓使用者輕鬆以適當方式共用資料。如要 相關資訊,請參閱關於目標 目標對象 ,直接在 Google Cloud 控制台實際操作。

目標對象的使用方法如下:

  1. 前往 Google 管理控制台的「選單」圖示 > 目錄 > 目標對象

    前往「目標對象」頁面

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

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

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

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

如要查看使用者與目標對象的互動情形,請參閱「連結的使用者體驗 分享 ,直接在 Google Cloud 控制台實際操作。

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

使用 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"
    }
  ]
}

驗證使用者權限

應用程式開啟檔案後,應檢查檔案的可否運作並順利顯示 使用者介面來反映目前使用者的權限。舉例來說,如果使用者 如果檔案沒有 canComment 功能,則能新增註解功能 應該在使用者介面停用

如要進一步瞭解 capabilities,請參閱功能

如要查看功能,請呼叫 files.get,以及 fileIdfields 參數,該參數已設為 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,並傳遞 fileIdpermissionIdfields 參數, permissionDetails 欄位。如要尋找 permissionId,請使用 使用 fileId 取代 permissions.list。目的地: 擷取 permissions.list 要求中的 permissionDetails 欄位,請設定 permissions/permissionDetailsfields 參數。

這個欄位會列出使用者所有繼承和直接檔案權限, 群組或網域

顯示範例

下列程式碼範例說明如何決定角色來源。回應會傳回 Permission 資源的 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.updatepermissionId變更權限和 fileId 相關聯的檔案、資料夾或共用雲端硬碟如要尋找 permissionId,請使用 使用 fileId 取代 permissions.list

  2. 在要求中,找出新的 role

即使沒有權限,你也能授予共用雲端硬碟中個別檔案或資料夾的權限 如果使用者或群組已是成員例如,小艾擁有 role=commenter 成為共用雲端硬碟的成員。不過,您的應用程式可授予小李 對共用雲端硬碟中的檔案來說,role=writer。因為新的角色 的權限比透過成員身分授予的角色更寬 權限將成為檔案或資料夾的有效角色

顯示範例

下列程式碼範例說明如何將檔案或資料夾的權限從加註者變更為寫入者。回應會傳回 Permission 資源的執行個體。

要求

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"
}

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

如要撤銷檔案或資料夾的存取權,請呼叫 delete,其中包含 fileIdpermissionId即可刪除權限。

「我的雲端硬碟」中的項目您可以刪除沿用的 權限。刪除繼承的權限後,系統會撤銷該項目的存取權, 子項目 (如果有的話)。

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

delete 作業也可用來刪除直接套用至 共用雲端硬碟的檔案或資料夾

顯示範例

下列程式碼範例說明如何刪除 permissionId 來撤銷存取權。如果成功,回應主體會是空白的。如要確認權限已移除,請搭配 fileId 使用 permissions.list

要求

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=owner》和《transferOwnership=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;
        }
    }
}