ファイル、フォルダ、ドライブを共有する

Google ドライブのファイル、フォルダ、共有ドライブには、それぞれ権限に関するリソースが関連付けられています。各リソースは、特定の type(ユーザー、グループ、ドメイン、すべてのユーザー)と role(「コメント」や「リーダー」など)の権限を識別します。たとえば、ファイルに特定のユーザー(type=user)に読み取り専用権限(role=reader)を付与する権限と、特定のグループのメンバー(type=group)にファイル(role=commenter)へのコメント権限を付与する権限があります。

ロールと、各ロールで許可されているオペレーションの一覧については、ロールをご覧ください。

ドライブのリソースを共有するシナリオ

共有シナリオには次の 5 種類があります。

  1. マイドライブでファイルを共有するには、ユーザーに role=writer 以上の権限を付与する必要があります。

    • ファイルの writersCanShare ブール値が False に設定されている場合、ユーザーには role=owner が必要です。

    • role=writer を持つユーザーが有効期限の日付と時刻によって管理される一時的なアクセス権を持っている場合、ファイルを共有することはできません。

    詳細については、有効期限を追加するをご覧ください。

  2. マイドライブ内のフォルダを共有するには、ユーザーに role=writer 以上の権限が必要です。

    • ファイルで writersCanShare ブール値が False に設定されている場合、ユーザーはより制限の厳しい role=owner を持っている必要があります。

    • role=writer を設定したマイドライブ フォルダには、有効期限付きの一時的アクセス権(有効期限で管理)を使用できません。

  3. 共有ドライブ内のファイルを共有するには、ユーザーに role=writer 以上のアクセス権が必要です。

    • writersCanShare 設定は共有ドライブ内のファイルには適用されません。 常に True に設定されているものとして扱われます。
  4. 共有ドライブ内のフォルダを共有するには、ユーザーに role=organizer の権限が必要です。

    • 共有ドライブの sharingFoldersRequiresOrganizerPermission の制限が False に設定されている場合、role=fileOrganizer を持つユーザーはその共有ドライブのフォルダを共有できます。
  5. ユーザーが共有ドライブのメンバーを管理するには、role=organizer が必要です。共有ドライブのメンバーになることができるのは、ユーザーとグループのみです。

権限の伝播

フォルダの権限リストは下方に伝播され、すべての子ファイルとフォルダは親から権限を継承します。権限または階層が変更されるたびに、すべてのネストされたフォルダを通じて伝播が再帰的に行われます。たとえば、ファイルがフォルダに存在し、そのフォルダが別のフォルダ内に移動された場合、新しいフォルダの権限がファイルに反映されます。新しいフォルダにより「writer」などの新しいロールがファイルに付与されると、以前のロールはオーバーライドされます。

逆に、ファイルがフォルダから role=writer を継承していて、「リーダー」ロールを提供する別のフォルダに移動した場合、ファイルは role=reader を継承するようになります。

継承された権限は、共有ドライブ内のファイルまたはフォルダから削除できません。 これらの権限は、継承された直接または間接の親で調整する必要があります。継承された権限は、[マイドライブ] または [共有アイテム] のアイテムから削除できます。

逆に、継承された権限は、マイドライブ内のファイルやフォルダでオーバーライドできます。そのため、ファイルがマイドライブ フォルダから role=writer を継承する場合は、ファイルの role=reader を設定して権限レベルを下げることができます。

機能

権限リソースによって、最終的に現在のユーザーがファイルまたはフォルダに対してアクションを実行できるかどうかが決まります。代わりに、Files リソースには、ファイルやフォルダに対してアクションを実行できるかどうかを示すブール値の capabilities フィールドのコレクションが含まれています。Google Drive API は、ファイルやフォルダに関連付けられた現在のユーザーの権限リソースに基づいて、これらのフィールドを設定します。

たとえば、Alex がアプリにログインしてファイルを共有しようとすると、ファイルの権限で Alex のロールがチェックされます。ロールでファイルを共有できる場合は、canShare などのファイルに関連する capabilities がロールに対して入力されています。Alex がファイル共有を行う場合、アプリは capabilities をチェックして canSharetrue に設定されていることを確認します。

権限を作成

権限を作成する場合は、次の 2 つのフィールドが必要です。

  • type - type は権限のスコープを示します(usergroupdomain、または anyone)。type=user 権限は特定のユーザーに適用され、type=domain 権限は特定のドメイン内のすべてのユーザーに適用されます。

  • role - role フィールドは、type が実行できるオペレーションを示します。たとえば、type=user および role=reader 権限を持つ権限は、特定のユーザーにファイルまたはフォルダへの読み取り専用アクセス権を付与します。または、type=domainrole=commenter の権限を持つと、ドメイン内の全員がファイルにコメントを追加できるようになります。ロールと、それぞれのロールによって許可されているオペレーションの一覧については、ロールをご覧ください。

type=user または type=group を使用して権限を作成する場合は、特定のユーザーまたはグループを権限に関連付ける emailAddress も指定する必要があります。

type=domain を使用して権限を作成する場合は、特定のドメインを権限に関連付ける domain も指定する必要があります。

権限を作成するには:

  1. 関連するファイルまたはフォルダの fileId を指定して、permissions.create メソッドを使用します。
  2. リクエストの本文で、typerole を特定します。
  3. type=user または type=group の場合は、emailAddress を指定します。type=domain の場合は、domain を指定します。

対象グループを使う

対象グループとは、アイテムの共有先としてユーザーに推奨できるグループ(部門やチームなど)のことです。アイテムの共有先を組織全体ではなく、一部の相手に絞るよう促すことができます。対象グループを使用すると、データのセキュリティとプライバシーを改善し、ユーザーが簡単に共有できるようになります。詳細については、対象グループについてをご覧ください。

対象グループを使用するには:

  1. Google 管理コンソールにログインします。

    このタスクの特権管理者権限を持つアカウントを使用してログインする必要があります。

  2. メニュー アイコン > [ディレクトリ] > [対象グループ] に移動します。

  3. 対象グループのリストで、対象グループの名前をクリックします。対象グループを作成するには、対象グループを作成するをご覧ください。

  4. 対象グループの URL から一意の ID をコピーします(https://admin.google.com/ac/targetaudiences/ID)。

  5. type=domain権限を作成し、domain フィールドを ID.audience.googledomains.com に設定します。

ユーザーが対象グループとやり取りする方法を確認するには、リンク共有のユーザー エクスペリエンスをご覧ください。

ファイル、フォルダ、共有ドライブに関するすべての権限を取得する

ファイル、フォルダ、共有ドライブに関するすべての権限を取得するには、permissions.list メソッドを使用します。

ユーザー権限を確認する

アプリがファイルを開くときは、そのファイルの機能をチェックして、現在のユーザーの権限を反映するように UI をレンダリングする必要があります。たとえば、ユーザーがファイルに canComment ケーパビリティがない場合は、UI でコメント機能を無効にする必要があります。

機能を確認するには、fileIdfields パラメータを capabilities フィールドに設定して files.get を呼び出します。

fields パラメータを使用してフィールドを返す方法については、ファイルの特定のフィールドを返すをご覧ください。

共有ドライブのファイルやフォルダのロールのソースを確認する

ファイルまたはフォルダのロールを変更するには、ロールのソースを把握している必要があります。共有ドライブの場合、共有ドライブのメンバーシップ、フォルダのロール、ファイルのロールに基づいてロールのソースを設定できます。

共有ドライブまたはドライブ内のアイテムのロールのソースを確認するには、fileIdpermissionIdfields パラメータを permissionDetails に設定して permissions.get を呼び出します。permissionId を見つけるには、permissions.listfileId を使用します。

このフィールドには、ユーザー、グループ、ドメインに対する、継承された直接のファイル権限がすべて列挙されます。

権限を変更

ファイルまたはフォルダの権限を変更するには、割り当てたロールを変更します。

  1. 変更する権限の permissionId と、関連するファイル、フォルダ、共有ドライブの fileId を指定して、permissions.update を呼び出します。permissionId を見つけるには、permissions.listfileId を使用します。

  2. リクエストで、新しい role を特定します。

ユーザーまたはグループがすでにメンバーになっている場合でも、共有ドライブ内の個々のファイルやフォルダに対する権限を付与できます。たとえば、Alex は共有ドライブのメンバーシップとして role=commenter を使用しています。ただし、共有ドライブ内のファイルに対する Alex に role=writer を付与することは可能です。この場合、新しいロールには、メンバーを通じて付与されるロールよりも制限の緩いため、新しい権限がファイルまたはフォルダの有効なロールになります。

ファイルまたはフォルダへのアクセス権を取り消す

ファイルまたはフォルダへのアクセス権を取り消すには、fileIdpermissionId を指定して delete を呼び出し、権限を削除します。

[マイドライブ] 内のアイテムについては、継承された権限を削除できます。 継承された権限を削除すると、アイテムと子アイテム(存在する場合)へのアクセス権も取り消されます。

共有ドライブ内のファイルの場合、継承された権限を取り消すことはできません。代わりに、親ファイルまたはフォルダの権限を更新または取り消してください。

delete オペレーションは、共有ドライブのファイルやフォルダに直接適用されている権限を削除するためにも使用されます。

同じ組織内の別の Google Workspace アカウントにファイルのオーナー権限を譲渡する

[マイドライブ] に存在するファイルのオーナー権限は、同じ Google Workspace アカウントから同じ組織内の別のアカウントに譲渡できます。共有ドライブを所有する組織は、そのドライブ内のファイルを所有します。そのため、共有ドライブ内のファイルやフォルダのオーナー権限の譲渡はサポートされていません。共有ドライブの主催者は、その共有ドライブから自分の [マイドライブ] にアイテムを移動して、オーナー権限を譲渡できます。

[マイドライブ] 内のファイルのオーナー権限を譲渡するには、次のいずれかを行います。

  • 特定のユーザー(type=user)にオーナー アクセス権を付与するファイル権限(role=owner)を作成します。

  • role=owner で既存のファイルの権限を更新し、指定したユーザー(transferOwnership=true)にオーナー権限を移行します。

別の一般ユーザー向けアカウントにファイルのオーナー権限を譲渡する

ファイルのオーナー権限は、一般ユーザー向けアカウント間で移行できます。ただし、移行先の新しいオーナーが移行に明示的に同意しない限り、ドライブでは 2 つの一般ユーザー向けアカウント間でファイルのオーナー権限が移行されません。ファイルのオーナー権限を別の一般ユーザー向けアカウントに移行するには:

  1. 現在のオーナーは、予定されている新しいオーナーのファイル権限を作成または更新することによってオーナー権限の譲渡を開始します。権限には、role=writertype=userpendingOwner=true の設定を含める必要があります。新しいオーナーに潜在的なオーナーの権限を作成する場合は、新しいオーナーに、ファイルの所有権を引き継ぐよう求められていることを知らせるメール通知が送信されます。

  2. 新しいオーナーは、ファイルの権限を作成または更新してオーナー権限の譲渡リクエストを承認します。権限には、role=ownertransferOwnership=true の設定を含める必要があります。新しいオーナーが新しい権限を作成すると、オーナー権限が譲渡されたことを知らせるメール通知が以前のオーナーに送信されます。

ファイルを移管すると、以前のオーナーのロールは writer にダウングレードされます。

バッチ リクエストを使用して複数の権限を変更する

複数の権限を変更する場合は、バッチ リクエストを使用することを強くおすすめします。

クライアント ライブラリを使用してバッチ権限を変更する例を次に示します。

Java

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

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

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

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

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


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

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

        ids.add(permission.getId());

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

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

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

      domainPermission.setDomain(realDomain);

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

      batch.execute();

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

Python

drive/snippets/drive-v3/file_snippet/share_file.py
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;
}

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