Compartilhar arquivos, pastas e drives

Cada arquivo, pasta e drive compartilhado do Google Drive tem recursos permissions associados. Cada recurso identifica a permissão para um type (user, group, domain, anyone) e um role (owner, organizer, fileOrganizer, writer, commenter, reader) específicos. Por exemplo, um arquivo pode ter uma permissão que concede a um usuário específico (type=user) acesso somente leitura (role=reader), enquanto outra permissão concede aos membros de um grupo específico (type=group) a capacidade de adicionar comentários a um arquivo (role=commenter).

Para ver uma lista completa de papéis e as operações permitidas por cada um, consulte Papéis e permissões.

Como as permissões são propagadas

As permissões são propagadas de cima para baixo, das pastas principais para todos os itens filhos:

  • Herdadas por padrão: todos os arquivos e pastas filhos herdam automaticamente permissões da pasta mãe.
  • Não pode ser reduzida em itens infantis: não é possível remover ou reduzir uma permissão herdada em um item infantil. As mudanças precisam ser feitas no pai de origem ou a pasta precisa usar a configuração de acesso limitado.
  • Pode ser expandido em filhos: um item filho pode conceder uma função mais permissiva, como conceder role=writer em um arquivo dentro de uma pasta em que o usuário tem role=reader.
  • Reavaliado na movimentação: mover um item para uma nova pasta principal reavalia e aplica as permissões da nova pasta ao item e aos filhos dele.

Links de arquivos e controle de acesso

Quando você compartilha um arquivo ou uma pasta com um usuário ou grupo específico, o URL para acessar o item não muda, e um link exclusivo não é gerado para cada usuário. Em vez disso, o item tem um único link constante com base no fileId dele.

O Drive controla o acesso avaliando a ACL do item. Quando um usuário tenta abrir um link, o Drive verifica a identidade autenticada dele em relação à ACL. Se uma permissão for revogada ou atingir a data de expiração, o usuário será removido da ACL. Se o usuário tentar acessar o link de novo, o Drive vai negar o acesso.

Entender os recursos de arquivos

O recurso permissions define quem tem acesso (a ACL), mas não indica diretamente se o usuário atual pode realizar uma ação específica na interface do aplicativo.

Em vez disso, o recurso files contém uma coleção de campos booleanos capabilities (como canComment, canShare ou canDelete) que a API Google Drive calcula dinamicamente com base na função do usuário e nas configurações do item.

Receber recursos de arquivo

Ao renderizar a interface do app, verifique files.capabilities em vez de analisar permissões diretamente:

  • Chame o método files.get com fields=capabilities. Para mais informações, consulte Retornar campos específicos.
  • Use as flags booleanas retornadas para ativar ou desativar as ações correspondentes na interface. Por exemplo, desative os comentários se canComment for false.

Cenários para compartilhar recursos do Drive

A tabela a seguir mostra as funções e condições necessárias para compartilhar recursos do Drive em diferentes locais e tipos de itens:

Local Item Funções exigidas Principais limitações
Meu Drive Arquivo ou pasta owner ou writer Exige owner se writersCanShare=false.
O acesso temporário em pastas exige reader. Consulte Definir uma data de expiração.
Drive compartilhado Arquivo organizer, fileOrganizer ou writer writersCanShare é sempre tratado como true.
Drive compartilhado Pasta organizer fileOrganizer também pode compartilhar se sharingFoldersRequiresOrganizerPermission for false.
Drive compartilhado Assinatura organizer Aplicável apenas a user ou group (não a domínios).

Gerenciar permissões

A tabela a seguir resume os métodos disponíveis no recurso permissions:

Método endpoint de API Parâmetros-chave Referência
Criar POST https://www.googleapis.com/drive/v3/files/{fileId}/permissions role, type, emailAddress ou domain permissions.create
Receber GET https://www.googleapis.com/drive/v3/files/{fileId}/permissions/{permissionId} fields permissions.get
List GET https://www.googleapis.com/drive/v3/files/{fileId}/permissions pageSize, supportsAllDrives, pageToken permissions.list
Atualizar PATCH https://www.googleapis.com/drive/v3/files/{fileId}/permissions/{permissionId} role, allowFileDiscovery permissions.update
Excluir DELETE https://www.googleapis.com/drive/v3/files/{fileId}/permissions/{permissionId} supportsAllDrives permissions.delete

Criar uma permissão

Para compartilhar um arquivo, uma pasta ou um drive compartilhado, chame o método create no recurso permissions com fileId. A criação de uma permissão adiciona uma nova entrada de ACL ao item e retorna um permissionId atribuído.

No corpo da solicitação, informe os seguintes campos:

  • role: o nível de acesso a ser concedido (por exemplo, reader, commenter ou writer). Para uma lista completa, consulte Papéis e permissões.
  • type: o escopo do beneficiário (user, group, domain ou anyone).
  • Identificador do beneficiário (obrigatório com base em type):
    • emailAddress: obrigatório quando type é user ou group.
    • domain: obrigatório quando type é domain.

O exemplo de código a seguir mostra como criar uma permissão. A resposta retorna uma instância de um recurso permissions, incluindo o permissionId atribuído.

Solicitação

POST https://www.googleapis.com/drive/v3/files/FILE_ID/permissions
{
  "role": "commenter",
  "type": "user",
  "emailAddress": "alex@altostrat.com"
}

Resposta

{
  "kind": "drive#permission",
  "id": "PERMISSION_ID",
  "type": "user",
  "role": "commenter"
}

Compartilhar com públicos-alvo

Os públicos-alvo são grupos de pessoas, como departamentos ou equipes, que você pode recomendar para os usuários compartilharem itens. Você pode incentivar os usuários a compartilhar itens com um público mais específico ou limitado, e não com toda a organização. Os públicos-alvo podem ajudar você a melhorar a segurança e a privacidade dos seus dados e facilitar o compartilhamento adequado pelos usuários.

Para compartilhar com um público-alvo, defina type=domain e domain como <TARGET_AUDIENCE_ID>.audience.googledomains.com. Para saber como localizar ou criar públicos-alvo no Google Admin Console, consulte Sobre públicos-alvo.

Para saber como os usuários interagem com os públicos-alvo, consulte Experiência do usuário para compartilhamento de links.

Receber uma permissão

Para receber uma permissão, chame o método get no recurso permissions com os parâmetros de caminho fileId e permissionId. Se você não souber o ID da permissão, liste todas as permissões primeiro.

Listar permissões

Para listar as permissões de um arquivo, uma pasta ou um drive compartilhado, chame o método list no recurso permissions com o parâmetro de caminho fileId necessário.

É possível incluir qualquer um dos seguintes parâmetros de consulta opcionais para paginar ou filtrar a resposta:

  • pageSize (opcional): o número máximo de permissões a serem retornadas por página. Se não for definido para arquivos em um drive compartilhado, no máximo 100 resultados serão retornados. Se não estiver definido para arquivos que não estão em um drive compartilhado, toda a lista será retornada.

  • pageToken (opcional): um token de página de uma chamada de lista anterior para recuperar a página subsequente.

  • supportsAllDrives (opcional): indica se o app solicitante é compatível com Meu Drive e drives compartilhados.

  • useDomainAdminAccess (opcional): defina como true para emitir a solicitação como um administrador de domínio. O acesso é concedido se o parâmetro fileId se referir a um drive compartilhado e o solicitante for administrador do domínio a que o drive pertence. Para mais informações, consulte Gerenciar drives compartilhados como administradores de domínio.

  • includePermissionsForView (opcional): outras permissões de visualização a serem incluídas na resposta. Somente published é aceito.

  • fields (opcional): campos específicos a serem retornados na resposta. Por padrão, list retorna apenas id, type, kind e role. Para retornar outros campos (como permissionDetails), especifique-os usando esse parâmetro. Para mais informações, consulte Retornar campos específicos.

Determinar a origem da função

Para mudar a função em um arquivo ou pasta, você precisa saber a origem dela. Para drives compartilhados, a origem de uma função pode ser baseada na participação no drive compartilhado, na função em uma pasta ou na função em um arquivo.

Para determinar a origem da função de um drive compartilhado ou dos itens nele, chame o método get no recurso permissions com os parâmetros de caminho fileId e permissionId, e o parâmetro fields definido como o campo permissionDetails.

Para encontrar o permissionId, use o método list no recurso permissions com o parâmetro de caminho fileId. Para buscar o campo permissionDetails na solicitação list, defina o parâmetro fields como permissions/permissionDetails.

Esse campo enumera todas as permissões de arquivo herdadas e diretas para o usuário, grupo ou domínio.

O exemplo de código a seguir mostra como determinar a origem da função. A resposta retorna o permissionDetails de um recurso permissions. O campo inheritedFrom fornece o ID do item de onde a permissão é herdada.

Solicitação

GET https://www.googleapis.com/drive/v3/files/FILE_ID/permissions/PERMISSION_ID?fields=permissionDetails&supportsAllDrives=true

Resposta

{
  "permissionDetails": [
    {
      "permissionType": "member",
      "role": "commenter",
      "inheritedFrom": "INHERITED_FROM_ID",
      "inherited": true
    },
    {
      "permissionType": "file",
      "role": "writer",
      "inherited": false
    }
  ]
}

Atualizar uma permissão

Para atualizar as permissões de um arquivo ou pasta, mude a função atribuída. Para mais informações sobre como encontrar a origem do papel, consulte Determinar a origem do papel.

  1. Chame o método update no recurso permissions com o parâmetro de caminho fileId definido como o arquivo, a pasta ou o drive compartilhado associado e o parâmetro de caminho permissionId definido como a permissão a ser alterada. Para encontrar o permissionId, use o método list no recurso permissions com o parâmetro de caminho fileId.

  2. Na solicitação, identifique o novo role.

Você pode conceder permissões em arquivos ou pastas individuais em um drive compartilhado, mesmo que o usuário ou grupo já seja um participante. Por exemplo, Alex tem role=commenter como parte da participação em um drive compartilhado. No entanto, seu app pode conceder a Alex role=writer para um arquivo em um drive compartilhado. Nesse caso, como a nova função é mais permissiva do que a função concedida pela assinatura, a nova permissão se torna a função efetiva para o arquivo ou a pasta.

É possível aplicar atualizações usando a semântica de patch, o que significa que você pode fazer modificações parciais em um recurso. É necessário definir explicitamente os campos que você pretende modificar na solicitação. Os campos não incluídos na solicitação mantêm os valores atuais. Para mais informações, consulte Como trabalhar com recursos parciais.

Além de mudar os papéis, também é possível modificar a capacidade de descoberta de um item quando a permissão type é domain ou anyone. Para tornar um arquivo compartilhado pesquisável ou não listado, inclua o campo booleano allowFileDiscovery na sua solicitação de patch. Definir como true permite que o item apareça nos resultados da pesquisa para o público-alvo especificado, mesmo que ele não tenha recebido o link direto. Não é necessário excluir e recriar a permissão para mudar essa configuração.

O exemplo de código a seguir mostra como mudar as permissões de um arquivo ou pasta de commenter para writer. A resposta retorna uma instância de um recurso permissions.

Solicitação

PATCH https://www.googleapis.com/drive/v3/files/FILE_ID/permissions/PERMISSION_ID
{
  "role": "writer"
}

Resposta

{
  "kind": "drive#permission",
  "id": "PERMISSION_ID",
  "type": "user",
  "role": "writer"
}

Atualizar várias permissões com solicitações em lote

Não é possível fazer modificações simultâneas nas permissões do mesmo arquivo, pasta ou drive compartilhado. Essa limitação se aplica a todas as operações de mutação (como atualização ou exclusão), independentemente de você estar modificando permissões para o mesmo destinatário ou destinatários diferentes e se as solicitações se originam de um único app ou de vários usuários.

O Drive avalia e atualiza as permissões de um item como uma única ACL. Operações simultâneas causam disputas em que "a última gravação vence", o que pode substituir silenciosamente as mudanças de permissão ou acionar erros de sharingRateLimitExceeded.

Para evitar conflitos, execute as mudanças de permissão no mesmo item de forma sequencial ou use solicitações em lote para modificar várias permissões em uma única solicitação.

Este é um exemplo de como fazer uma modificação de permissão em lote com uma biblioteca de cliente.

Java

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

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

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

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

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


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

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

        ids.add(permission.getId());

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

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

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

      domainPermission.setDomain(realDomain);

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

      batch.execute();

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

Python

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


def share_file(real_file_id, real_user, real_domain):
  """Batch permission modification.
  Args:
      real_file_id: file Id
      real_user: User ID
      real_domain: Domain of the user ID
  Prints modified permissions

  Load pre-authorized user credentials from the environment.
  TODO(developer) - See https://developers.google.com/identity
  for guides on implementing OAuth2 for the application.
  """
  creds, _ = google.auth.default()

  try:
    # create drive api client
    service = build("drive", "v3", credentials=creds)
    ids = []
    file_id = real_file_id

    def callback(request_id, response, exception):
      if exception:
        # Handle error
        print(exception)
      else:
        print(f"Request_Id: {request_id}")
        print(f'Permission Id: {response.get("id")}')
        ids.append(response.get("id"))

    # pylint: disable=maybe-no-member
    batch = service.new_batch_http_request(callback=callback)
    user_permission = {
        "type": "user",
        "role": "writer",
        "emailAddress": "user@example.com",
    }
    batch.add(
        service.permissions().create(
            fileId=file_id,
            body=user_permission,
            fields="id",
        )
    )
    domain_permission = {
        "type": "domain",
        "role": "reader",
        "domain": "example.com",
    }
    domain_permission["domain"] = real_domain
    batch.add(
        service.permissions().create(
            fileId=file_id,
            body=domain_permission,
            fields="id",
        )
    )
    batch.execute()

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

  return ids


if __name__ == "__main__":
  share_file(
      real_file_id="1dUiRSoAQKkM3a4nTPeNQWgiuau1KdQ_l",
      real_user="gduser1@workspacesamples.dev",
      real_domain="workspacesamples.dev",
  )

Node.js

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

/**
 * Shares a file with a user and a domain.
 * @param {string} fileId The ID of the file to share.
 * @param {string} targetUserEmail The email address of the user to share with.
 * @param {string} targetDomainName The domain to share with.
 * @return {Promise<Array<string>>} A promise that resolves to an array of permission IDs.
 */
async function shareFile(fileId, targetUserEmail, targetDomainName) {
  // 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});

  /** @type {Array<string>} */
  const permissionIds = [];

  // The permissions to create.
  const permissions = [
    {
      type: 'user',
      role: 'writer',
      emailAddress: targetUserEmail, // e.g., 'user@partner.com'
    },
    {
      type: 'domain',
      role: 'writer',
      domain: targetDomainName, // e.g., 'example.com'
    },
  ];

  // Iterate through the permissions and create them one by one.
  for (const permission of permissions) {
    const result = await service.permissions.create({
      requestBody: permission,
      fileId,
      fields: 'id',
    });

    if (result.data.id) {
      permissionIds.push(result.data.id);
      console.log(`Inserted permission id: ${result.data.id}`);
    } else {
      throw new Error('Failed to create permission');
    }
  }
  return permissionIds;
}

PHP

drive/snippets/drive_v3/src/DriveShareFile.php
<?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;
        }
    }
}

Excluir uma permissão

Para revogar o acesso a um arquivo ou pasta, chame o método delete no recurso permissions com os parâmetros de caminho fileId e permissionId.

Não é possível revogar permissões herdadas diretamente em itens filhos. Atualize ou exclua a permissão na pasta principal (ou use a configuração de acesso limitado).

Observação: remover o acesso de um usuário de um item principal revoga apenas as permissões herdadas desse item. Se o usuário também tiver recebido permissões diretas em um item filho, esse acesso direto vai continuar. Para confirmar que uma permissão foi removida, chame list com o fileId.

Defina a data de validade

Para conceder acesso temporário a um arquivo ou pasta, defina o campo expirationTime (data e hora RFC 3339) ao chamar os métodos create ou update.

Os tempos de expiração têm as seguintes restrições:

  • Só pode ser definido nas permissões user e group (não domain ou anyone).
  • O horário precisa ser no futuro, até um máximo de um ano.
  • Para pastas, o acesso temporário só é compatível com a função reader.