مشاركة الملفات والمجلدات ومحركات الأقراص

يرتبط كل ملف ومجلدات ومساحة تخزين سحابي مشتركة في Google Drive بموارد الأذونات. يحدّد كل مورد الإذن لـ type محدّد (مستخدم أو مجموعة أو نطاق أو أي شخص) وrole، مثل "معلِّق" أو "قارئ". على سبيل المثال، قد يحصل ملف على إذن لمنح مستخدم محدد (type=user) إذن بالقراءة فقط (role=reader) بينما يمنح إذن آخر أعضاء مجموعة محددة (type=group) إمكانية إضافة تعليقات إلى ملف (role=commenter).

للحصول على قائمة كاملة بالأدوار والعمليات التي يسمح بها كل طرف، يمكنك الاطّلاع على الأدوار والأذونات.

سيناريوهات مشاركة موارد Drive

هناك خمسة أنواع مختلفة من سيناريوهات المشاركة:

  1. لمشاركة ملف في "ملفاتي"، يجب أن يكون لدى المستخدم role=writer أو role=owner.

    • في حال ضبط القيمة المنطقية writersCanShare على False للملف، يجب أن يكون لدى المستخدم role=owner.

    • إذا كان المستخدم الذي يملك الملف role=writer لديه إذن وصول مؤقت يخضع لتاريخ ووقت انتهاء الصلاحية، لن يتمكّن من مشاركة الملف.

    ولمزيد من المعلومات، يمكنك الاطّلاع على إضافة تاريخ انتهاء صلاحية.

  2. لمشاركة مجلد في "ملفاتي"، يجب أن يكون لدى المستخدم role=writer أو role=owner.

    • وإذا تم ضبط القيمة المنطقية writersCanShare على False للملف، يجب أن يكون لدى المستخدم قيمة role=owner الأكثر تساهلاً.

    • لا يُسمح بالوصول المؤقت (الذي يخضع لتاريخ ووقت انتهاء الصلاحية) إلى مجلدات "ملفاتي" التي تتضمن role=writer.

  3. لمشاركة ملف في مساحة تخزين سحابي مشتركة، يجب أن يكون لدى المستخدم role=writer أو role=fileOrganizer أو role=organizer.

    • لا ينطبق الإعداد writersCanShare على العناصر في مساحات التخزين السحابي المشتركة. ويتم التعامل معه كما لو كان مضبوطًا دائمًا على القيمة True.
  4. لمشاركة مجلد في مساحة تخزين سحابي مشتركة، يجب أن يكون لدى المستخدم role=organizer.

    • في حال ضبط القيد sharingFoldersRequiresOrganizerPermission في مساحة تخزين سحابي مشتركة على False، يمكن للمستخدمين الذين لديهم role=fileOrganizer مشاركة المجلدات في مساحة التخزين السحابي المشتركة هذه.
  5. لإدارة عضوية مساحة التخزين السحابي المشتركة، يجب أن يكون لدى المستخدم role=organizer. يمكن للمستخدمين والمجموعات فقط أن يكونوا أعضاء في مساحات التخزين السحابي المشتركة.

نشر الأذونات

يتم نشر قوائم الأذونات لمجلد للأسفل، وتكتسب جميع الملفات والمجلدات الفرعية الأذونات من المجلد الرئيسي. كلما تم تغيير الأذونات أو التسلسل الهرمي، يحدث النشر بشكل متكرر من خلال جميع المجلدات المدمجة. على سبيل المثال، إذا كان هناك ملف في مجلد وتم نقله بعد ذلك داخل مجلد آخر، يتم نشر الأذونات في المجلد الجديد إلى الملف. إذا منح المجلد الجديد المستخدم دورًا جديدًا في الملف، مثل "كاتب"، سيتم إلغاؤه.

وفي المقابل، إذا كان الملف تكتسب role=writer من مجلد، وتم نقله إلى مجلد آخر يوفّر دور "القارئ"، يكتسِب الملف الآن role=reader.

لا يمكن إزالة الأذونات المكتسَبة من ملف أو مجلد في مساحة تخزين سحابي مشتركة. بدلاً من ذلك، يجب تعديل هذه الأذونات على العنصر الرئيسي المباشر أو غير المباشر الذي تم اكتسابها منه. يمكن إزالة الأذونات المكتسبة من العناصر ضمن "ملفاتي" أو "تمت مشاركتها معي".

وبالعكس، يمكن إلغاء الأذونات المكتسَبة في ملف أو مجلد في ملفاتي. إذا كان الملف تكتسب role=writer من مجلد "ملفاتي"، يمكنك ضبط role=reader في الملف لخفض مستوى إذنه.

الإمكانيات

لا يحدِّد مورد الأذونات في النهاية إمكانية المستخدم في تنفيذ إجراءات على ملف أو مجلد. وبدلاً من ذلك، يحتوي مورد الملفات على مجموعة من حقول capabilities المنطقية التي يتم استخدامها للإشارة إلى ما إذا كان يمكن تنفيذ الإجراء على ملف أو مجلد. وتضبط Google Drive API هذه الحقول استنادًا إلى مورد أذونات المستخدم الحالي المرتبط بالملف أو المجلد.

على سبيل المثال، عندما يسجّل Alex الدخول إلى تطبيقك ويحاول مشاركة ملف، يتم التحقق من دور Alex من حيث الأذونات في الملف. إذا كان الدور يسمح لهم بمشاركة ملف، يتم ملء capabilities المرتبط بالملف، مثل canShare، بالنسبة إلى الدور. إذا أراد أليكس مشاركة الملف، سيتحقّق تطبيقك من capabilities للتأكّد من ضبط canShare على true.

إنشاء إذن

يجب ملء الحقلَين التاليَين عند إنشاء إذن:

  • type: يحدِّد type نطاق الإذن (user أو group أو domain أو anyone). وينطبق الإذن الذي يحتوي على type=user على مستخدم مُحدَّد، بينما يسري الإذن الذي يحمل type=domain على جميع المستخدمين في نطاق معيَّن.

  • role: يحدّد الحقل role العمليات التي يمكن type تنفيذها. على سبيل المثال، يمنح إذن في type=user وrole=reader مستخدمًا معيّنًا إذن بالقراءة فقط على الملف أو المجلد. أو يسمح الإذن باستخدام type=domain وrole=commenter لجميع المستخدمين في النطاق بإضافة تعليقات إلى ملف. للحصول على قائمة كاملة بالأدوار والعمليات التي يسمح بها كل طرف، يمكنك الرجوع إلى الأدوار.

عند إنشاء إذن حيث يكون type=user أو type=group، عليك أيضًا تقديم emailAddress لربط المستخدم أو المجموعة المحددة بالإذن.

عند إنشاء إذن حيث يكون type=domain، عليك أيضًا تقديم domain لربط نطاق محدد بالإذن.

لإنشاء إذن:

  1. استخدام الطريقة permissions.create مع fileId للملف أو المجلد المرتبط
  2. في نص الطلب، حدِّد type وrole.
  3. إذا type=user أو type=group، أدخِل emailAddress. إذا كانت السمة type=domain، قدِّم السمة domain.

استخدام الجماهير المستهدفة

الجماهير المستهدفة هي مجموعات من الأشخاص، مثل الأقسام أو الفِرق، يمكنك اقتراحها للمستخدمين لمشاركة العناصر معهم. يمكنك تشجيع المستخدمين على مشاركة العناصر مع جمهور محدد أكثر أو محدود بدلاً من المؤسسة بأكملها. يمكن أن تساعدك الجماهير المستهدفة في تحسين أمان بياناتك وخصوصيتها، وتسهيل مشاركة المستخدمين لها بشكل مناسب. لمزيد من المعلومات، اطّلِع على لمحة عن الجماهير المستهدفة.

لاستخدام الجماهير المستهدفة:

  1. سجّل الدخول إلى وحدة تحكّم المشرف في Google.

    يجب أن تُسجَّل الدخول باستخدام حساب يمتلك امتيازات المشرف المتميّز لهذه المهمة.

  2. انتقِل إلى القائمة > الدليل > الجماهير المستهدفة.

  3. في قائمة الجماهير المستهدفة، انقر على اسم الجمهور المستهدف. لإنشاء جمهور مستهدف، يُرجى الاطّلاع على إنشاء جمهور مستهدف.

  4. انسخ المعرّف الفريد من عنوان URL للجمهور المستهدف: https://admin.google.com/ac/targetaudiences/ID.

  5. أنشئ إذنًا باستخدام type=domain، واضبط الحقل domain على ID.audience.googledomains.com.

لعرض كيفية تفاعل المستخدمين مع الجماهير المستهدفة، يُرجى الاطّلاع على تجربة المستخدم للمشاركة باستخدام رابط .

استرداد جميع الأذونات الخاصة بأحد الملفات أو المجلدات أو مساحات التخزين السحابي المشتركة

يمكنك استخدام طريقة permissions.list لاسترداد جميع الأذونات لملف أو مجلد أو مساحة تخزين سحابي مشتركة.

التحقق من أذونات المستخدم

عندما يفتح تطبيقك ملفًا، عليك التحقق من إمكانات الملف وعرض واجهة المستخدم لإظهار أذونات المستخدم الحالي. على سبيل المثال، إذا لم تتوفّر لدى المستخدم إمكانية canComment على الملف، يجب إيقاف إمكانية التعليق في واجهة المستخدم.

وللتحقّق من الإمكانات، يمكنك طلب files.get مع ضبط المَعلمة fileId والمَعلمة fields على الحقل capabilities.

للحصول على مزيد من المعلومات عن الحقول المعروضة باستخدام المَعلمة fields، يمكنك الرجوع إلى عرض حقول محدّدة لملف.

تحديد مصدر الدور للملفات والمجلدات في مساحة التخزين السحابي المشتركة

لتغيير الدور على ملف أو مجلد، عليك معرفة مصدر الدور. بالنسبة إلى مساحات التخزين السحابي المشتركة، يمكن أن يعتمد مصدر الدور على الاشتراك في مساحة التخزين السحابي المشتركة أو الدور في مجلد أو الدور في ملف.

لتحديد مصدر الدور لمساحة تخزين سحابي مشتركة أو عناصر ضمن مساحة التخزين السحابي هذه، اطلب permissions.get مع ضبط المعلَمة fileId وpermissionId وfields على permissionDetails. للعثور على permissionId، استخدِم permissions.list مع fileId.

يعدّد هذا الحقل كل أذونات الملفات المكتسَبة والمباشرة للمستخدم أو المجموعة أو النطاق.

تغيير الأذونات

لتغيير الأذونات في ملف أو مجلد، يمكنك تغيير الدور المخصّص له:

  1. الاتصال بـ permissions.update مع منح permissionId الإذن بالتغيير وfileId للملف أو المجلد أو مساحة التخزين السحابي المشتركة المرتبطة. للعثور على permissionId، استخدِم permissions.list مع fileId.

  2. في الطلب، حدِّد السمة الجديدة role.

يمكنك منح أذونات لملفات أو مجلدات فردية في مساحة تخزين سحابي مشتركة حتى إذا كان المستخدم أو المجموعة عضوًا حاليًا. على سبيل المثال، لدى "أليكس" role=commenter كجزء من اشتراكه في مساحة تخزين سحابي مشتركة. ومع ذلك، يمكن لتطبيقك منح Alex role=writer لملف في مساحة تخزين سحابي مشتركة. في هذه الحالة، ولأنّ الدور الجديد أكثر تساهلاً من الدور الذي تم منحه من خلال هذا العضوية، يصبح الإذن الجديد الدور الفعّال للملف أو المجلد.

إبطال إذن الوصول إلى ملف أو مجلد

لإبطال الوصول إلى ملف أو مجلد، اطلب delete من خلال fileId و permissionId لحذف الإذن.

بالنسبة إلى العناصر في "ملفاتي"، من الممكن حذف إذن مكتسَب. يؤدي حذف إذن مكتسب إلى إبطال إمكانية الوصول إلى العنصر والعناصر الثانوية، إن توفّرت.

بالنسبة إلى العناصر في مساحة التخزين السحابي المشتركة، لا يمكن إبطال الأذونات المكتسَبة. يمكنك تعديل الإذن في الملف أو المجلد الرئيسي بدلاً من ذلك أو إبطاله.

تُستخدَم عملية delete أيضًا لحذف الأذونات المطبَّقة مباشرةً على مجلد أو ملف مساحة تخزين سحابي مشتركة.

نقل ملكية الملف إلى حساب Google Workspace آخر في المؤسسة نفسها

يمكن نقل ملكية الملفات الحالية في "ملفاتي" من حساب Google Workspace إلى حساب آخر في المؤسسة نفسها. تمتلك المؤسسة التي تمتلك مساحة تخزين سحابي مشتركة الملفات بداخلها. لذلك، لا تتوفّر عمليات نقل الملكية للملفات والمجلدات في مساحات التخزين السحابي المشتركة. يمكن لمنظّمي مساحة التخزين السحابي المشتركة نقل عناصر من مساحة التخزين السحابي المشتركة هذه إلى "ملفاتي" التي تنقل الملكية إليها.

لنقل ملكية ملف في "ملفاتي"، نفِّذ أحد الإجراءات التالية:

  • إنشاء إذن ملف يمنح مستخدمًا محددًا (type=user) إذن وصول المالك (role=owner).

  • عدِّل إذن ملف حالي باستخدام role=owner وانقل الملكية إلى المستخدم المحدَّد (transferOwnership=true).

نقل ملكية الملفات من حساب مستهلك إلى حساب آخر

يمكن نقل ملكية الملفات بين حساب مستهلك إلى حساب آخر. مع ذلك، لا ينقل Drive ملكية الملف بين حسابَي مستهلكين حتى يوافق المالك المحتمل الجديد على عملية النقل. لنقل ملكية الملفات من حساب مستهلك إلى حساب آخر:

  1. يبدأ المالك الحالي نقل الملكية عن طريق إنشاء إذن تعديل مالك المالك الجديد المحتمل أو تعديله. ويجب أن يتضمّن الإذن الإعدادات التالية: role=writer وtype=user وpendingOwner=true. وإذا كان المالك الجديد ينشئ إذنًا للمالك المحتمل، يتم إرسال إشعار عبر البريد الإلكتروني إلى المالك الجديد المحتمل يشير إلى أنّه يُطلب منه تولّي ملكية الملف.

  2. يقبل المالك الجديد طلب نقل الملكية من خلال إنشاء إذن الملف أو تعديله. ويجب أن يتضمّن الإذن الإعدادات التالية: role=owner وtransferOwnership=true. إذا كان المالك الجديد ينشئ إذنًا جديدًا، يتم إرسال إشعار عبر البريد الإلكتروني إلى المالك السابق يشير إلى أنه تم نقل الملكية.

عند نقل ملف، يتم خفض مستوى دور المالك السابق إلى writer.

تغيير الأذونات المتعددة باستخدام الطلبات المجمّعة

ونقترح بشدة استخدام الطلبات المجمّعة لتعديل أذونات متعددة.

إليك مثال على إجراء تعديل مجمّع للأذونات باستخدام مكتبة برامج.

لغة Java

drive/snippets/drive_v3/src/main/java/ShareFilejava.
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/snippet/drive-v3/file_snippet/share_file.py
from __future__ import print_function

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

‫2,999

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