ניהול של תיקיות אחסון שיתופי

במסמך הזה מפורטות משימות שקשורות לניהול תיקיות באחסון השיתופי, כמו יצירת תיקיות באחסון השיתופי וניהול חברים והרשאות, באמצעות Google Drive API.

אם רוצים לציין את השדות שיוחזרו בתגובה, אפשר להגדיר את fields פרמטר המערכת בכל שיטה של משאב drives. אם לא מציינים את הפרמטר fields, השרת מחזיר קבוצת שדות שמוגדרת כברירת מחדל וספציפית לשיטה. לדוגמה, השיטה list מחזירה רק את השדות kind, id ו-name של כל תיקיית אחסון שיתופי. מידע נוסף זמין במאמר בנושא החזרת שדות ספציפיים.

מידע נוסף על מגבלות על תיקיות באחסון שיתופי זמין במאמר מגבלות על תיקיות באחסון שיתופי.

דרישות מוקדמות

כדי ליצור תיקיות באחסון השיתופי ולנהל אותן, צריך לוודא שאתם עומדים בדרישות הבאות:

  • חשבון Google Workspace: תיקיות משותפות זמינות במהדורות נתמכות של Google Workspace (כמו Business Standard,‏ Business Plus,‏ Enterprise ו-Education). בחשבונות Google אישיים (@gmail.com) אי אפשר ליצור תיקיות אחסון שיתופי.
  • הרשאת יצירה: אדמינים של דומיין יכולים להגדיר אם משתמשים בארגון שלהם יכולים ליצור תיקיות אחסון שיתופי. המשתמש המאומת צריך להשתייך ליחידה ארגונית שיש לה הרשאה ליצור תיקיות אחסון שיתופי.
  • היקף הרשאות OAuth 2.0: האפליקציה צריכה לקבל הרשאה עם היקף ההרשאות https://www.googleapis.com/auth/drive.
  • תפקידים: כשמשתמש יוצר אחסון שיתופי, הוא מקבל באופן אוטומטי את התפקיד organizer באחסון השיתופי הזה. כדי לנהל את ההגדרות של האחסון השיתופי, לשנות את השם שלו, להוסיף או להסיר חברים ולמחוק את האחסון השיתופי, צריך להיות בעלי תפקיד organizer. מידע נוסף על תפקידים זמין במאמר תפקידים בתיקיות משותפות.
  • גישה של אדמין בדומיין: אדמינים בדומיין יכולים לנהל כל תיקיית אחסון שיתופי בארגון שלהם, בלי קשר לחברות שלהם בה, על ידי העברת useDomainAdminAccess=true. מידע נוסף זמין במאמר בנושא ניהול של תיקיות משותפות כאדמינים של הדומיין.

יצירת אחסון שיתופי

כדי ליצור אחסון שיתופי, משתמשים בשיטה create במשאב drives עם הפרמטר requestId.

הפרמטר requestId מזהה את הניסיון הלוגי ליצירה אידמפוטנטית של אחסון שיתופי. אם פג הזמן הקצוב לתגובה לבקשה או שהבקשה מחזירה שגיאת קצה עורפי לא מוגדרת, אפשר לשלוח את אותה בקשה שוב ולא ייווצרו כפילויות. ה-requestId וגוף הבקשה צריכים להישאר ללא שינוי.

בדוגמת הקוד הבאה אפשר לראות איך יוצרים תיקייה באחסון השיתופי:

Java

drive/snippets/drive_v3/src/main/java/CreateDrive.java
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
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.DriveScopes;
import com.google.api.services.drive.model.Drive;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Arrays;
import java.util.UUID;

/* class to demonstrate use-case of Drive's create drive. */
public class CreateDrive {

  /**
   * Create a drive.
   *
   * @return Newly created drive id.
   * @throws IOException if service account credentials file not found.
   */
  public static String createDrive() 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.*/
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Arrays.asList(DriveScopes.DRIVE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

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

    Drive driveMetadata = new Drive();
    driveMetadata.setName("Project Resources");
    String requestId = UUID.randomUUID().toString();
    try {
      Drive drive = service.drives().create(requestId,
              driveMetadata)
          .execute();
      System.out.println("Drive ID: " + drive.getId());

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

Python

drive/snippets/drive-v3/drive_snippet/create_drive.py
import uuid

import google.auth
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError


def create_drive():
  """Create a drive.
  Returns:
      Id of the created drive

  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)

    drive_metadata = {"name": "Project Resources"}
    request_id = str(uuid.uuid4())
    # pylint: disable=maybe-no-member
    drive = (
        service.drives()
        .create(body=drive_metadata, requestId=request_id, fields="id")
        .execute()
    )
    print(f'Drive ID: {drive.get("id")}')

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

  return drive.get("id")


if __name__ == "__main__":
  create_drive()

Node.js

drive/snippets/drive_v3/drive_snippets/create_drive.js
import {GoogleAuth} from 'google-auth-library';
import {google} from 'googleapis';
import {v4 as uuid} from 'uuid';

/**
 * Creates a new shared drive.
 * @return {Promise<string>} The ID of the created shared drive.
 */
async function createDrive() {
  // Authenticate with Google and get an authorized client.
  // TODO (developer): Use an appropriate auth mechanism for your app.
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Drive API client (v3).
  const service = google.drive({version: 'v3', auth});

  // The metadata for the new shared drive.
  const driveMetadata = {
    name: 'Project resources',
  };

  // A unique request ID to avoid creating duplicate shared drives.
  const requestId = uuid();

  // Create the new shared drive.
  const Drive = await service.drives.create({
    requestBody: driveMetadata,
    requestId,
    fields: 'id',
  });

  // Print the ID of the new shared drive.
  console.log('Drive Id:', Drive.data.id);
  if (!Drive.data.id) {
    throw new Error('Drive ID not found.');
  }
  return Drive.data.id;
}

PHP

drive/snippets/drive_v3/src/DriveCreateDrive.php
<?php
use Google\Client;
use Google\Service\Drive;
use Ramsey\Uuid\Uuid;
function createDrive()
{
    try {
        $client = new Client();
        $client->useApplicationDefaultCredentials();
        $client->addScope(Drive::DRIVE);
        $driveService = new Drive($client);

        $driveMetadata = new Drive\Drive(array(
                'name' => 'Project Resources'));
        $requestId = Uuid::uuid4()->toString();
        $drive = $driveService->drives->create($requestId, $driveMetadata, array(
                'fields' => 'id'));
        printf("Drive ID: %s\n", $drive->id);
        return $drive->id;
    } catch(Exception $e)  {
        echo "Error Message: ".$e;
    }  

}

‎.NET

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

namespace DriveV3Snippets
{
    // Class to demonstrate use of Drive's create drive.
    public class CreateDrive
    {
        /// <summary>
        /// Create a drive.
        /// </summary>
        /// <returns>newly created drive Id.</returns>
        public static string DriveCreateDrive()
        {
            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 driveMetadata = new Drive()
                {
                    Name = "Project Resources"
                };
                var requestId = Guid.NewGuid().ToString();
                var request = service.Drives.Create(driveMetadata, requestId);
                request.Fields = "id";
                var drive = request.Execute();
                Console.WriteLine("Drive ID: " + drive.Id);
                return drive.Id;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

הקריאות לשיטה create הן אידמפוטנטיות.

אם האחסון השיתופי נוצר בהצלחה בבקשה קודמת או בעקבות ניסיון חוזר, הפונקציה מחזירה מופע של משאב drives. לפעמים, למשל אחרי זמן ממושך או אם גוף הבקשה השתנה, יכול להיות שתוחזר 409 שגיאה שמציינת שצריך לבטל את requestId.

קבלת אחסון שיתופי

כדי לקבל מטא-נתונים של תיקיית אחסון שיתופי, משתמשים בשיטה get במשאב drives עם פרמטר הנתיב driveId. אם אתם לא יודעים את מזהה ה-Drive, אתם יכולים לרשום את כל תיקיות האחסון השיתופי באמצעות method‏ list.

השיטה get מחזירה אחסון שיתופי כמופע של משאב drives.

כדי להגיש את הבקשה כאדמין של הדומיין, צריך להגדיר את פרמטר השאילתה useDomainAdminAccess לערך true. מידע נוסף זמין במאמר בנושא ניהול תיקיות אחסון שיתופי כאדמינים של הדומיין.

רשימת תיקיות אחסון שיתופי

כדי להציג רשימה של תיקיות אחסון שיתופי של משתמש, משתמשים בשיטה list במשאב drives. השיטה מחזירה רשימה של תיקיות אחסון שיתופי.

כדי להתאים אישית את המספור של תיקיות אחסון שיתופי או לסנן אותן, צריך להעביר את פרמטרי השאילתה הבאים:

  • pageSize: המספר המקסימלי של תיקיות באחסון השיתופי שיוחזרו בכל דף.

  • pageToken: טוקן של דף שהתקבל מקריאה קודמת של list. צריך להזין את הטוקן הזה כדי לאחזר את הדף הבא.

  • q: מחרוזת שאילתה לחיפוש בכונני אחסון שיתופיים. מידע נוסף זמין במאמר בנושא חיפוש תיקיות באחסון השיתופי.

  • useDomainAdminAccess: צריך להגדיר את הערך true כדי לשלוח את הבקשה כמנהל דומיין, וכך לקבל את כל תיקיות האחסון השיתופי בדומיין שבו השולח הוא מנהל. מידע נוסף זמין במאמר בנושא ניהול של תיקיות משותפות כאדמינים של הדומיין.

עדכון אחסון שיתופי

כדי לעדכן את המטא-נתונים של אחסון שיתופי, משתמשים בשיטה update במשאב drives עם פרמטר הנתיב driveId.

השיטה מחזירה אחסון שיתופי כמופע של משאב drives.

כדי להגיש את הבקשה כאדמין של הדומיין, צריך להגדיר את פרמטר השאילתה useDomainAdminAccess לערך true. מידע נוסף זמין במאמר בנושא ניהול תיקיות אחסון שיתופי כאדמינים של הדומיין.

הסתרה וביטול הסתרה של אחסון שיתופי

כדי להסתיר אחסון שיתופי מהתצוגה שמוגדרת כברירת מחדל, משתמשים בשיטה hide במשאב drives עם הפרמטר driveId.

כשמסתירים אחסון שיתופי, הוא מסומן ב-Drive כhidden=true. תיקיות אחסון שיתופי מוסתרות לא מופיעות בממשק המשתמש של Drive או ברשימת הקבצים שמוחזרים.

כדי לשחזר תיקיית אחסון שיתופי לתצוגת ברירת המחדל, משתמשים בשיטה unhide במשאב drives עם הפרמטר driveId.

שתי השיטות מחזירות אחסון שיתופי כמופע של משאב drives.

מחיקת אחסון שיתופי

כדי למחוק אחסון שיתופי באופן סופי, משתמשים בשיטה delete במשאב drives עם הפרמטר driveId.

לפני שמוחקים אחסון שיתופי, צריך להעביר את כל התוכן שבו לאשפה או למחוק אותו. למשתמש צריכות להיות גם הרשאות role=organizer בתיקייה באחסון השיתופי. מידע נוסף זמין במאמר בנושא העברה של קבצים ותיקיות לאשפה או מחיקה שלהם.

מעבירים את הפרמטרים הבאים של השאילתה:

  • useDomainAdminAccess: מגדירים את הערך ל-true כדי לשלוח את הבקשה בתור אדמין של הדומיין. מידע נוסף זמין במאמר בנושא ניהול תיקיות אחסון שיתופי כאדמינים של הדומיין.

  • allowItemDeletion: מוגדר כ-true כדי למחוק פריטים בתיקיית האחסון השיתופי. המאפיין הזה נתמך רק אם המאפיין useDomainAdminAccess מוגדר גם הוא לערך true.

הוספה או הסרה של חברים באחסון השיתופי

מוסיפים חברים לאחסון השיתופי או מסירים אותם ממנו באמצעות מקור המידע permissions.

כדי להוסיף חבר, צריך ליצור את ההרשאה באחסון השיתופי. אפשר גם להשתמש בשיטות להענקת הרשאות לקבצים בודדים בתיקיית אחסון שיתופי, כדי להעניק לחברים הרשאות נוספות או לאפשר למי שלא חברים בתיקייה לשתף פעולה בפריטים ספציפיים.

מידע נוסף וקוד לדוגמה זמינים במאמר בנושא שיתוף קבצים, תיקיות ו-Drive.

ניהול של תיקיות אחסון שיתופי כאדמינים של הדומיין

אפשר להשתמש בפרמטר useDomainAdminAccess עם המשאבים drives ו-permissions כדי לנהל תיקיות באחסון השיתופי בכל הארגון.

משתמשים שמפעילים את השיטות האלה עם useDomainAdminAccess=true צריכים להיות בעלי הרשאת אדמין של Drive and Docs. אדמינים יכולים לחפש תיקיות באחסון השיתופי או לעדכן הרשאות לתיקיות באחסון השיתופי שנמצאות בבעלות הארגון, ללא קשר לחברות של האדמין בתיקייה מסוימת באחסון השיתופי.

כשמשתמשים בחשבונות שירות, יכול להיות שיהיה צורך להתחזות לאדמין מאומת באמצעות התחזות לחשבון שירות. חשוב לזכור: חשבונות שירות לא שייכים לדומיין שלכם ב-Google Workspace, בניגוד לחשבונות משתמשים. אם אתם משתפים נכסים ב-Google Workspace, כמו מסמכים או אירועים, ברמת הדומיין ב-Google Workspace, הם לא ישותפו עם חשבונות שירות. מידע נוסף מופיע במאמר סקירה כללית על חשבונות שירות.

שחזור של אחסון שיתופי שאין לו מארגן

בדוגמת הקוד הבאה אפשר לראות איך לשחזר תיקיות באחסון השיתופי שכבר אין להן מארגן.

Java

drive/snippets/drive_v3/src/main/java/RecoverDrive.java
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.DriveScopes;
import com.google.api.services.drive.model.Drive;
import com.google.api.services.drive.model.DriveList;
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 Drive's shared drive without an organizer. */
public class RecoverDrive {

  /**
   * Find all shared drives without an organizer and add one.
   *
   * @param realUser User's email id.
   * @return All shared drives without an organizer.
   * @throws IOException if shared drive not found.
   */
  public static List<Drive> recoverDrives(String realUser)
      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.*/
    GoogleCredentials credentials =
        GoogleCredentials.getApplicationDefault().createScoped(Arrays.asList(DriveScopes.DRIVE));
    HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(
        credentials);

    // Build a new authorized API client service.
    com.google.api.services.drive.Drive service =
        new com.google.api.services.drive.Drive.Builder(new NetHttpTransport(),
            GsonFactory.getDefaultInstance(),
            requestInitializer)
            .setApplicationName("Drive samples")
            .build();
    List<Drive> drives = new ArrayList<Drive>();

    // Find all shared drives without an organizer and add one.
    // Note: This example does not capture all cases. Shared drives
    // that have an empty group as the sole organizer, or an
    // organizer outside the organization are not captured. A
    // more exhaustive approach would evaluate each shared drive
    // and the associated permissions and groups to ensure an active
    // organizer is assigned.
    String pageToken = null;
    Permission newOrganizerPermission = new Permission()
        .setType("user")
        .setRole("organizer");

    newOrganizerPermission.setEmailAddress(realUser);


    do {
      DriveList result = service.drives().list()
          .setQ("organizerCount = 0")
          .setFields("nextPageToken, drives(id, name)")
          .setUseDomainAdminAccess(true)
          .setPageToken(pageToken)
          .execute();
      for (Drive drive : result.getDrives()) {
        System.out.printf("Found drive without organizer: %s (%s)\n",
            drive.getName(), drive.getId());
        // Note: For improved efficiency, consider batching
        // permission insert requests
        Permission permissionResult = service.permissions()
            .create(drive.getId(), newOrganizerPermission)
            .setUseDomainAdminAccess(true)
            .setSupportsAllDrives(true)
            .setFields("id")
            .execute();
        System.out.printf("Added organizer permission: %s\n",
            permissionResult.getId());

      }

      drives.addAll(result.getDrives());

      pageToken = result.getNextPageToken();
    } while (pageToken != null);

    return drives;
  }
}

Python

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


def recover_drives(real_user):
  """Find all shared drives without an organizer and add one.
  Args:
      real_user:User ID for the new organizer.
  Returns:
      drives object

  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)

    drives = []

    # pylint: disable=maybe-no-member
    page_token = None
    new_organizer_permission = {
        "type": "user",
        "role": "organizer",
        "emailAddress": "user@example.com",
    }
    new_organizer_permission["emailAddress"] = real_user

    while True:
      response = (
          service.drives()
          .list(
              q="organizerCount = 0",
              fields="nextPageToken, drives(id, name)",
              useDomainAdminAccess=True,
              pageToken=page_token,
          )
          .execute()
      )
      for drive in response.get("drives", []):
        print(
            "Found shared drive without organizer: "
            f"{drive.get('title')}, {drive.get('id')}"
        )
        permission = (
            service.permissions()
            .create(
                fileId=drive.get("id"),
                body=new_organizer_permission,
                useDomainAdminAccess=True,
                supportsAllDrives=True,
                fields="id",
            )
            .execute()
        )
        print(f'Added organizer permission: {permission.get("id")}')

      drives.extend(response.get("drives", []))
      page_token = response.get("nextPageToken", None)
      if page_token is None:
        break

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

  return drives


if __name__ == "__main__":
  recover_drives(real_user="gduser1@workspacesamples.dev")

Node.js

drive/snippets/drive_v3/drive_snippets/recover_drives.js
import {GoogleAuth} from 'google-auth-library';
import {google} from 'googleapis';

/**
 * Finds all shared drives without an organizer and adds one.
 * @param {string} userEmail The email of the user to assign ownership to.
 * @return {Promise<object[]>} A list of the recovered drives.
 */
async function recoverDrives(userEmail) {
  // Authenticate with Google and get an authorized client.
  // TODO (developer): Use an appropriate auth mechanism for your app.
  const auth = new GoogleAuth({
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Drive API client (v3).
  const service = google.drive({version: 'v3', auth});

  // The permission to add to the shared drive.
  const newOrganizerPermission = {
    type: 'user',
    role: 'organizer',
    emailAddress: userEmail, // e.g., 'user@example.com'
  };

  // List all shared drives with no organizers.
  const result = await service.drives.list({
    q: 'organizerCount = 0',
    fields: 'nextPageToken, drives(id, name)',
    useDomainAdminAccess: true,
  });

  // Add the new organizer to each found shared drive.
  for (const drive of result.data.drives ?? []) {
    if (!drive.id) {
      continue;
    }

    console.log('Found shared drive without organizer:', drive.name, drive.id);
    await service.permissions.create({
      requestBody: newOrganizerPermission,
      fileId: drive.id,
      useDomainAdminAccess: true,
      supportsAllDrives: true,
      fields: 'id',
    });
  }
  return result.data.drives ?? [];
}

PHP

drive/snippets/drive_v3/src/DriveRecoverDrives.php
<?php
use Google\Client;
use Google\Service\Drive;
use Ramsey\Uuid\Uuid;
function recoverDrives()
{
   try {
    $client = new Client();
    $client->useApplicationDefaultCredentials();
    $client->addScope(Drive::DRIVE);
    $driveService = new Drive($client);

    $realUser = readline("Enter user email address: ");

    $drives = array();
    // Find all shared drives without an organizer and add one.
    // Note: This example does not capture all cases. Shared drives
    // that have an empty group as the sole organizer, or an
    // organizer outside the organization are not captured. A
    // more exhaustive approach would evaluate each shared drive
    // and the associated permissions and groups to ensure an active
    // organizer is assigned.
    $pageToken = null;
    $newOrganizerPermission = new Drive\Permission(array(
        'type' => 'user',
        'role' => 'organizer',
        'emailAddress' => 'user@example.com'
    ));
    $newOrganizerPermission['emailAddress'] = $realUser;
    do {
        $response = $driveService->drives->listDrives(array(
            'q' => 'organizerCount = 0',
            'fields' => 'nextPageToken, drives(id, name)',
            'useDomainAdminAccess' => true,
            'pageToken' => $pageToken
        ));
        foreach ($response->drives as $drive) {
            printf("Found shared drive without organizer: %s (%s)\n",
                $drive->name, $drive->id);
            $permission = $driveService->permissions->create($drive->id,
                $newOrganizerPermission,
                array(
                    'fields' => 'id',
                    'useDomainAdminAccess' => true,
                    'supportsAllDrives' => true
                ));
            printf("Added organizer permission: %s\n", $permission->id);
        }
        array_push($drives, $response->drives);
        $pageToken = $response->pageToken;
    } while ($pageToken != null);
    return $drives;
   } catch(Exception $e) {
      echo "Error Message: ".$e;
   }
}

‎.NET

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

namespace DriveV3Snippets
{
    // Class to demonstrate use-case of Drive's shared drive without an organizer.
    public class RecoverDrives
    {
        /// <summary>
        /// Find all shared drives without an organizer and add one.
        /// </summary>
        /// <param name="realUser">User ID for the new organizer.</param>
        /// <returns>all shared drives without an organizer.</returns>
        public static IList<Drive> DriveRecoverDrives(string realUser)
        {
            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 drives = new List<Drive>();
                // Find all shared drives without an organizer and add one.
                // Note: This example does not capture all cases. Shared drives
                // that have an empty group as the sole organizer, or an
                // organizer outside the organization are not captured. A
                // more exhaustive approach would evaluate each shared drive
                // and the associated permissions and groups to ensure an active
                // organizer is assigned.
                string pageToken = null;
                var newOrganizerPermission = new Permission()
                {
                    Type = "user",
                    Role = "organizer",
                    EmailAddress = realUser
                };

                do
                {
                    var request = service.Drives.List();
                    request.UseDomainAdminAccess = true;
                    request.Q = "organizerCount = 0";
                    request.Fields = "nextPageToken, drives(id, name)";
                    request.PageToken = pageToken;
                    var result = request.Execute();
                    foreach (var drive in result.Drives)
                    {
                        Console.WriteLine(("Found abandoned shared drive: {0} ({1})",
                            drive.Name, drive.Id));
                        // Note: For improved efficiency, consider batching
                        // permission insert requests
                        var permissionRequest = service.Permissions.Create(
                            newOrganizerPermission,
                            drive.Id
                        );
                        permissionRequest.UseDomainAdminAccess = true;
                        permissionRequest.SupportsAllDrives = true;
                        permissionRequest.Fields = "id";
                        var permissionResult = permissionRequest.Execute();
                        Console.WriteLine("Added organizer permission: {0}", permissionResult.Id);
                    }

                    pageToken = result.NextPageToken;
                } while (pageToken != null);

                return drives;
            }
            catch (Exception e)
            {
                // TODO(developer) - handle error appropriately
                if (e is AggregateException)
                {
                    Console.WriteLine("Credential Not found");
                }
                else
                {
                    throw;
                }
            }
            return null;
        }
    }
}

איך מונעים ממשתמשים להוריד, להדפיס או להעתיק קבצים

אתם יכולים להגביל את האופן שבו משתמשים יכולים להוריד, להדפיס ולהעתיק קבצים באחסון שיתופי.

כדי לבדוק אם המשתמש יכול לשנות הגבלות על הורדה שהוגדרו על ידי המארגן בתיקיית אחסון שיתופי, בודקים את השדה הבוליאני capabilities.canChangeDownloadRestriction. אם הערך של capabilities.canChangeDownloadRestriction הוא true, אפשר להחיל הגבלות על ההורדה של קבצים מהאחסון השיתופי. מידע נוסף זמין במאמר בנושא הסבר על יכולות הקבצים.

המשאב drives מכיל אוסף של שדות בוליאניים restrictions שמשמשים לציון האם אפשר לבצע פעולה באחסון שיתופי. ההגבלות חלות על אחסון שיתופי או על פריטים בתוך אחסון שיתופי. אפשר להגדיר הגבלות באמצעות ה-method‏ drives.update.

כדי להחיל הגבלות על הורדה באחסון שיתופי, מנהל האחסון השיתופי יכול להגדיר את השדה restrictions.downloadRestriction של המשאב drives באמצעות האובייקט DownloadRestriction. הגדרת restrictedForReaders השדה הבוליאני לערך true מציינת שגם ההורדה וגם ההעתקה מוגבלות לקוראים. הגדרת restrictedForWriters השדה הבוליאני לערך true מציינת שגם ההורדה וגם ההעתקה מוגבלות למשתמשים עם הרשאת כתיבה. שימו לב: אם הערך בשדה restrictedForWriters הוא true, גם הקוראים לא יוכלו להוריד ולהעתיק את המסמך. באופן דומה, הגדרת restrictedForWriters ל-true והגדרת restrictedForReaders ל-false שוות להגדרת restrictedForWriters ו-restrictedForReaders ל-true.

תאימות לדורות קודמים

עם ההשקה של האובייקט DownloadRestriction, עודכנה הפונקציונליות של השדה הבוליאני restrictions.copyRequiresWriterPermission.

עכשיו, הגדרת restrictions.copyRequiresWriterPermission ל-true מעדכנת את השדה הבוליאני restrictedForReaders של האובייקט DownloadRestriction ל-true כדי להצהיר שגם ההורדה וגם ההעתקה מוגבלות לקוראים.

הגדרת השדה copyRequiresWriterPermission ל-false מעדכנת את השדות restrictedForWriters ו-restrictedForReaders ל-false. המשמעות היא שהגדרות ההגבלה על הורדה או העתקה יוסרו עבור כל המשתמשים.

שדות ששולטים בתכונות של הורדה, הדפסה והעתקה

בטבלה הבאה מפורטים שדות המשאבים drives שמשפיעים על הפונקציות של הורדה, הדפסה והעתקה:

שדה תיאור גרסה
capabilities.canCopy האם המשתמש הנוכחי יכול להעתיק קבצים באחסון השיתופי. גרסה 2 וגרסה 3
capabilities.canDownload האם המשתמש הנוכחי יכול להוריד קבצים באחסון השיתופי. גרסה 2 וגרסה 3
capabilities.canChangeCopyRequiresWriterPermissionRestriction האם המשתמש הנוכחי יכול לשנות את ההגבלה copyRequiresWriterPermission של תיקיית אחסון שיתופי. גרסה 2 וגרסה 3
capabilities.canResetDriveRestrictions האם המשתמש הנוכחי יכול לאפס את ההגבלות של האחסון השיתופי להגדרות ברירת המחדל. גרסה 2 וגרסה 3
capabilities.canChangeDownloadRestriction האם המשתמש הנוכחי יכול לשנות את הגבלת ההורדה של תיקיית אחסון שיתופי. גרסה 3 בלבד
restrictions.copyRequiresWriterPermission האם האפשרויות להעתקה, להדפסה או להורדה של קבצים בתוך אחסון שיתופי מושבתות למשתמשים עם הרשאת קריאה והרשאת תגובה. אם true, השדה עם השם הדומה מוגדר ל-true לכל קובץ באחסון השיתופי הזה. גרסה 2 וגרסה 3
restrictions.downloadRestriction הגבלות ההורדה שהוגדרו על ידי מנהלים של האחסון השיתופי. גרסה 3 בלבד

מגבלות על תיקיות

באחסון שיתופי יש מגבלות על עומק הפריטים והתיקיות. בנוסף, השימוש בנפח האחסון מנוהל לפי נפח האחסון המשותף של הארגון, ולא לפי מכסת נפח האחסון האישי של משתמש ספציפי בתיקייה'האחסון שלי'. מידע נוסף זמין במאמר מגבלות על אחסון שיתופי ב-Google Drive.

מכסת פריטים

אפשר לאחסן עד 500,000 פריטים באחסון שיתופי, כולל קבצים, תיקיות וקיצורי דרך.

כשהמכסה תיגמר, לא תהיה אפשרות להוסיף פריטים לאחסון השיתופי. כדי להמשיך לקבל קבצים, המשתמשים צריכים למחוק באופן סופי פריטים מהאחסון השיתופי. שימו לב: פריטים באשפה נספרים במגבלה, אבל פריטים שנמחקו באופן סופי לא נספרים. מידע נוסף זמין במאמר בנושא העברה לאשפה או מחיקה של קבצים ותיקיות.

מגבלת עומק התיקייה

תיקייה באחסון שיתופי לא יכולה להכיל יותר מ-100 רמות של תיקיות מקוננות. כלומר, אי אפשר לאחסן תיקיית צאצא בתיקייה שנמצאת ברמה עמוקה יותר מ-99. ההגבלה הזו חלה רק על תיקיות צאצא.

ניסיונות להוסיף יותר מ-100 רמות של תיקיות מחזירים תגובה עם קוד סטטוס של HTTP‏ teamDriveHierarchyTooDeep.