Делитесь файлами, папками и дисками

Каждый файл, папка и общий диск Google Drive имеют связанные ресурсы permissions . Каждый ресурс определяет разрешение для определенного type ( user , group , domain , anyone ) и role ( owner , organizer , организатор fileOrganizer , writer , commenter , reader ). Например, файл может иметь разрешение, предоставляющее определенному пользователю ( type=user ) доступ только для чтения ( role=reader ), в то время как другое разрешение предоставляет членам определенной группы ( type=group ) возможность добавлять комментарии к файлу ( role=commenter ).

Полный список ролей и разрешенных каждой из них операций см. в разделе Роли и разрешения .

Как работают разрешения

Списки разрешений для папки распространяются сверху вниз. Все дочерние файлы и папки наследуют разрешения от родительского. Всякий раз, когда разрешения или иерархия изменяются, распространение происходит рекурсивно по всем вложенным папкам. Например, если файл существует в папке, а затем эта папка перемещается в другую папку, разрешения новой папки распространяются на файл. Если новая папка предоставляет пользователю файла новую роль, например «писатель», она переопределяет его старую роль.

И наоборот, если файл наследует role=writer от папки и перемещается в другую папку, которая предоставляет роль «читатель», файл теперь наследует role=reader .

Унаследованные разрешения не могут быть удалены из файла или папки на общем диске. Вместо этого эти разрешения должны быть скорректированы на прямом или косвенном родителе, от которого они были унаследованы. Унаследованные разрешения могут быть удалены из элементов в разделе «Мой диск» или «Доступно мне».

И наоборот, унаследованные разрешения могут быть переопределены для файла или папки в Моем диске. Таким образом, если файл наследует role=writer из папки Моего диска, вы можете установить role=reader для файла, чтобы понизить его уровень разрешений.

Понять возможности файлов

Ресурс permissions в конечном итоге не определяет способность текущего пользователя выполнять действия с файлом или папкой. Вместо этого ресурс files содержит набор полей логических capabilities , используемых для указания того, можно ли выполнить действие с файлом или папкой. API Google Drive устанавливает эти поля на основе ресурса разрешений текущего пользователя, связанного с файлом или папкой.

Например, когда Алекс входит в ваше приложение и пытается поделиться файлом, роль Алекса проверяется на наличие разрешений на файл. Если роль позволяет им делиться файлом, capabilities связанные с файлом, такие как canShare , заполняются относительно роли. Если Алекс хочет поделиться файлом, ваше приложение проверяет capabilities , чтобы убедиться, что canShare установлен в true .

Пример получения capabilities файла см. в разделе Получение возможностей файла .

Получить возможности файла

Когда ваше приложение открывает файл, оно должно проверить возможности файла и отобразить пользовательский интерфейс, чтобы отразить разрешения текущего пользователя. Например, если у пользователя нет возможности canComment для файла, возможность комментирования должна быть отключена в пользовательском интерфейсе.

Чтобы проверить возможности, вызовите метод get() на ресурсе files с параметром пути 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
  }
}

Сценарии совместного использования ресурсов Диска

Существует пять различных типов сценариев обмена:

  1. Чтобы поделиться файлом в Моем диске, пользователь должен иметь role=writer или role=owner .

  2. Чтобы предоставить общий доступ к папке в Моем диске, пользователь должен иметь role=writer или role=owner .

  3. Чтобы предоставить общий доступ к файлу на общем диске, пользователь должен иметь role=writer , role=fileOrganizer или role=organizer .

    • Параметр writersCanShare не применяется к элементам на общих дисках. Он рассматривается так, как будто он всегда установлен в true .
  4. Чтобы предоставить общий доступ к папке на общем диске, пользователь должен иметь role=organizer .

    • Если ограничение sharingFoldersRequiresOrganizerPermission для общего диска установлено на false , пользователи с role=fileOrganizer могут предоставлять общий доступ к папкам на этом общем диске.
  5. Для управления членством в общем диске пользователь должен иметь role=organizer . Только пользователи и группы могут быть членами общих дисков.

Создать разрешение

При создании разрешения необходимы следующие два поля:

  • 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. Используйте метод create() с параметром пути fileId для связанного файла или папки.
  2. В теле запроса укажите type и role .
  3. Если type=user или type=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. Скопируйте уникальный идентификатор из URL целевой аудитории: https://admin.google.com/ac/targetaudiences/ ID .

  4. Создайте разрешение с type=domain и установите для поля domain значение ID .audience.googledomains.com .

Чтобы узнать, как пользователи взаимодействуют с целевой аудиторией, см. раздел Пользовательский опыт при обмене ссылками .

Список всех разрешений

Используйте метод list() ресурса permissions , чтобы получить все разрешения для файла, папки или общего диска.

Следующий пример кода показывает, как получить все разрешения. Ответ возвращает список разрешений.

Запрос

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

Обновление разрешений

Чтобы обновить разрешения на файл или папку, вы можете изменить назначенную роль. Для получения дополнительной информации о поиске источника роли см. Определение источника роли .

  1. Вызовите метод update() на ресурсе permissions с параметром пути permissionId , установленным на разрешение на изменение, и параметром пути fileId , установленным на связанный файл, папку или общий диск. Чтобы найти permissionId , используйте метод list() на ресурсе permissions с параметром пути fileId .

  2. В запросе укажите новую role .

Вы можете предоставить разрешения на отдельные файлы или папки на общем диске, даже если пользователь или группа уже являются участниками. Например, у Алекса есть role=commenter как часть его членства на общем диске. Однако ваше приложение может предоставить Алексу 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"
}

Определить источник роли

Чтобы изменить роль для файла или папки, необходимо знать источник роли. Для общих дисков источник роли может быть основан на членстве в общем диске, роли для папки или роли для файла.

Чтобы определить источник роли для общего диска или элементов на этом диске, вызовите метод get() для ресурса permissions с параметрами пути fileId и permissionId , а параметр fields задайте равным полю permissionDetails .

Чтобы найти permissionId , используйте метод list() на ресурсе permissions с параметром пути fileId . Чтобы извлечь поле permissionDetails в запросе list , установите параметр fields на permissions/permissionDetails .

В этом поле перечислены все унаследованные и прямые разрешения на доступ к файлам для пользователя, группы или домена.

Следующий пример кода показывает, как определить источник роли. Ответ возвращает permissionDetails ресурса permissions . Поле inheritedFrom предоставляет идентификатор элемента, от которого наследуется разрешение.

Запрос

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

Обновление нескольких разрешений с помощью пакетных запросов

Мы настоятельно рекомендуем использовать пакетные запросы для изменения нескольких разрешений.

Ниже приведен пример выполнения пакетного изменения разрешений с помощью клиентской библиотеки.

Ява

диск/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;
    }
  }
}

Питон

диск/фрагменты/диск-v3/файл_фрагмент/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

диск/фрагменты/диск_v3/файл_фрагменты/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;
    }

}

.СЕТЬ

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

Удалить разрешение

Чтобы отозвать доступ к файлу или папке, вызовите метод delete() для ресурса permissions с параметрами fileId и permissionId , установленными для удаления разрешения.

Для элементов в "Моем диске" можно удалить унаследованное разрешение. Удаление унаследованного разрешения отменяет доступ к элементу и дочерним элементам, если таковые имеются.

Для элементов на общем диске унаследованные разрешения не могут быть отозваны. Вместо этого обновите или удалите разрешение на родительский файл или папку.

Метод delete() также используется для удаления разрешений, непосредственно примененных к файлу или папке общего диска.

Следующий пример кода показывает, как отозвать доступ, удалив permissionId . В случае успеха тело ответа пустое. Чтобы подтвердить удаление разрешения, используйте метод list() на ресурсе permissions с параметром пути fileId .

Запрос

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

Установите дату истечения срока действия, чтобы ограничить доступ к файлу

Когда вы работаете с людьми над важным проектом, вы можете захотеть ограничить их доступ к определенным файлам на Диске после определенного периода времени. Для файлов на Моем Диске вы можете установить дату истечения срока действия, чтобы ограничить или удалить доступ к этому файлу.

Чтобы установить дату истечения срока действия:

  • Используйте метод create() на ресурсе permissions и установите поле expirationTime (вместе с другими обязательными полями). Для получения дополнительной информации см. Создание разрешения .

  • Используйте метод update() на ресурсе permissions и установите поле expirationTime (вместе с другими обязательными полями). Для получения дополнительной информации см. Обновление разрешений .

Поле expirationTime обозначает, когда истекает срок действия разрешения, используя дату-время RFC 3339. Срок действия имеет следующие ограничения:

  • Их можно устанавливать только на уровне разрешений пользователей и групп.
  • Время должно быть в будущем.
  • Время не может быть больше, чем через год.

Более подробную информацию о сроке годности можно найти в следующих статьях: