Cómo compartir archivos, carpetas y unidades

Stay organized with collections Save and categorize content based on your preferences.

Cada archivo, carpeta y unidad compartida de Google Drive tienen recursos Permissions asociados. Cada recurso identifica el permiso para un type (usuario, grupo, dominio, cualquiera) y role, como "comentarista" o "lector". Por ejemplo, un archivo puede tener un permiso que otorga a un usuario específico (type=user) acceso de solo lectura (role=reader), mientras que otro permiso otorga a los miembros de un grupo específico (type=group) la capacidad de agregar comentarios a un archivo (role=commenter).

Para obtener una lista completa de las funciones y las operaciones que permite cada una, consulta Funciones.

Casos de uso compartido de recursos de Drive

Existen 5 tipos diferentes de situaciones de uso compartido:

  1. Para compartir un archivo en Mi unidad, el usuario debe tener la función de "escritor" o superior.

    • Si el valor booleano writersCanShare se establece en False para el archivo, el usuario debe tener la función “propietario”.

    • Si el usuario con la función de “escritor” tiene acceso temporal regido por una fecha y hora de vencimiento, no puede compartir el archivo.

    Para obtener más información, consulta Agrega una fecha de vencimiento.

  2. Para compartir una carpeta en Mi unidad, el usuario debe tener la función de "escritor" o superior.

    • Si el valor booleano writersCanShare se establece en False para el archivo, el usuario debe tener la función más permisiva "propietario".

    • No se permite el acceso temporal (gobernado por una fecha y hora de vencimiento) en las carpetas de Mi unidad con la función de “escritor”.

  3. Para compartir un archivo en una unidad compartida, el usuario debe tener la función de "escritor" o superior.

    • La configuración writersCanShare no se aplica a los elementos de las unidades compartidas. Se trata como si siempre se configurara como True.

    • No se permite el acceso temporal (regido por una fecha y hora de vencimiento) en las unidades compartidas.

  4. Para compartir una carpeta en una unidad compartida, el usuario debe tener la función de “organizador”.

  5. Para administrar la membresía de la unidad compartida, el usuario debe tener la función de “organizador”. Solo los usuarios y los grupos pueden ser miembros de las unidades compartidas.

Propagación de permisos

Las listas de permisos de una carpeta se propagan hacia abajo, y todas las carpetas y los archivos secundarios heredan los permisos del elemento superior. Cuando se cambian los permisos o la jerarquía, la propagación ocurre de manera recursiva en todas las carpetas anidadas. Por ejemplo, si un archivo existe en una carpeta y esa carpeta se mueve dentro de otra carpeta, los permisos de la carpeta nueva se propagan al archivo. Si la carpeta nueva otorga al usuario del archivo una función nueva, como "escritor", anula su función anterior.

Por el contrario, si un archivo hereda la función de “escritor” de una carpeta y se mueve a otra carpeta que proporciona la función de “lector”, el archivo hereda la función de “lector”.

Los permisos heredados no se pueden quitar de un archivo o una carpeta de una unidad compartida. En cambio, estos permisos deben ajustarse en relación con el elemento superior directo o indirecto del que se heredaron. Los permisos heredados se pueden quitar de los elementos en "Mi unidad" o "Compartidos conmigo".

Por el contrario, los permisos heredados se pueden anular en un archivo o una carpeta de Mi unidad. Por lo tanto, si un archivo hereda la función de "escritor" de una carpeta de Mi unidad, puedes establecer la función de "lector" en el archivo para bajar su nivel de permiso.

Funciones

En última instancia, el recurso Permissions no determina la capacidad del usuario actual para realizar acciones en un archivo o una carpeta. En cambio, un recurso Files contiene una colección de campos capabilities booleanos que se usan para indicar si una acción se puede realizar en un archivo o una carpeta. La API de Google Drive establece estos campos en función del recurso de permisos del usuario actual asociado con el archivo o la carpeta.

Por ejemplo, cuando Alex accede a tu app e intenta compartir un archivo, la función de Alex se verifica en términos de permisos en el archivo. Si la función les permite compartir un archivo, los capabilities relacionados con el archivo, como canShare, se completan en relación con la función. Si Alex quiere compartir el archivo, tu app verifica la capabilities para asegurarse de que canShare esté configurado como true.

Crear un permiso

Los siguientes 2 campos son necesarios cuando se crea un permiso:

  • type: El type identifica el permiso del permiso (user, group, domain o anyone). Un permiso con type=user se aplica a un usuario específico, mientras que un permiso con type=domain se aplica a todos en un dominio específico.

  • role: El campo role identifica las operaciones que puede realizar type. Por ejemplo, un permiso con type=user y role=reader otorga a un usuario específico acceso de solo lectura al archivo o a la carpeta. O bien, un permiso con type=domain y role=commenter permite que todos los miembros del dominio agreguen comentarios a un archivo. Para obtener una lista completa de las funciones y las operaciones que permite cada una, consulta Funciones.

Cuando creas un permiso en el que type=user o type=group, también debes proporcionar un emailAddress para vincular el usuario o grupo específico al permiso.

Cuando creas un permiso en el que type=domain, también debes proporcionar un domain para vincular un dominio específico al permiso.

Para crear un permiso, haz lo siguiente:

  1. Usa el método permissions.create con el fileId para el archivo o la carpeta asociados.
  2. En el cuerpo de la solicitud, identifica type y role.
  3. Si es type=user o type=group, proporciona un emailAddress. Si es type=domain, proporciona un domain.

Recuperar todos los permisos de un archivo, una carpeta o una unidad compartida

Usa el método permissions.list a fin de recuperar todos los permisos para un archivo, una carpeta o una unidad compartida.

Verifica los permisos del usuario

Cuando tu app abre un archivo, debe comprobar sus capacidades y representar la IU para reflejar los permisos del usuario actual. Por ejemplo, si el usuario no tiene una función canComment en el archivo, la capacidad de comentar debe estar inhabilitada en la IU.

Para verificar las capacidades, llama a files.get con los parámetros fileId y fields establecidos en el campo capabilities.

Para obtener más información sobre cómo mostrar campos con el parámetro fields, consulta Muestra campos específicos para un archivo.

Determina la fuente de la función de los archivos y las carpetas de la unidad compartida

Para cambiar la función de un archivo o una carpeta, debes conocer la fuente de la función. En el caso de las unidades compartidas, la fuente de una función puede basarse en la membresía de la unidad compartida, la función en una carpeta o la función en un archivo.

Para determinar el origen de la función de una unidad compartida o de los elementos dentro de ella, llama a permissions.get con los parámetros fileId, permissionId y fields establecidos en el campo permissionDetails. Para encontrar el permissionId, usa permissions.list con el fileId.

En este campo, se enumeran todos los permisos de archivos directos y heredados para el usuario, el grupo o el dominio.

Cambiar permisos

Para cambiar los permisos de un archivo o una carpeta, puedes cambiar la función asignada:

  1. Llama a permissions.update con el permissionId del permiso para cambiar y a fileId para el archivo, la carpeta o la unidad compartida asociados. Para encontrar el permissionId, usa permissions.list con el fileId.

  2. En la solicitud, identifica el role nuevo.

Puedes otorgar permisos en archivos o carpetas individuales de una unidad compartida, incluso si el usuario o grupo ya es miembro. Por ejemplo, Alex tiene la función de commenter como parte de su membresía a una unidad compartida. Sin embargo, tu app puede otorgar a Alex la función writer para un archivo en una unidad compartida. En este caso, debido a que la función nueva es más permisiva que la función otorgada a través de su membresía, el permiso nuevo se convierte en la función efectiva para el archivo o la carpeta.

Cómo revocar el acceso a un archivo o una carpeta

Si quieres revocar el acceso a un archivo o una carpeta, llama a delete con fileId y permissionId para borrar el permiso.

Para los elementos de "Mi unidad", es posible borrar un permiso heredado. Borrar un permiso heredado revoca el acceso al elemento y a los elementos secundarios, si lo hubiera.

Para los elementos de una unidad compartida, los permisos heredados no se pueden revocar. En su lugar, actualiza o revoca el permiso en el archivo o la carpeta superiores.

La operación delete también se usa para borrar los permisos aplicados directamente a un archivo o una carpeta de una unidad compartida.

Cómo transferir la propiedad de un archivo a otra cuenta de Google Workspace de la misma organización

La propiedad de los archivos existentes en “Mi unidad” se puede transferir de una cuenta de Google Workspace a otra en la misma organización. Una organización que es propietaria de una unidad compartida posee los archivos dentro de ella. Por lo tanto, las transferencias de propiedad no son compatibles con los archivos y las carpetas de las unidades compartidas. Los organizadores de una unidad compartida pueden mover elementos de esa unidad compartida a su propia “Mi unidad”, que les transfiere la propiedad.

Para transferir la propiedad de un archivo en "Mi unidad", realiza una de las siguientes acciones:

  • Crea un permiso de archivo para otorgar acceso de propietario (role=owner) a un usuario específico (type=user).

  • Actualiza el permiso de un archivo existente con la función owner y transfiere la propiedad al usuario especificado (transferOwnership=true).

Cómo transferir la propiedad de un archivo de una cuenta personal a otra

La propiedad de los archivos se puede transferir entre una cuenta personal y otra. Sin embargo, Drive no transfiere la propiedad de un archivo entre 2 cuentas personales hasta que el nuevo propietario potencial da su consentimiento explícito para la transferencia. Para transferir la propiedad de los archivos de una cuenta personal a otra, sigue estos pasos:

  1. Para iniciar una transferencia de propiedad, el propietario actual crea o actualiza el permiso de archivo del nuevo propietario potencial. El permiso debe incluir estas opciones de configuración: role=writer, type=user y pendingOwner=true. Si el propietario nuevo crea un permiso para el propietario potencial, se le envía una notificación por correo electrónico a fin de indicarle que se le solicita que asuma la propiedad del archivo.

  2. Para aceptar la solicitud de transferencia de propiedad, el propietario nuevo debe crear o actualizar el permiso de archivo. El permiso debe incluir esta configuración: role=owner y transferOwnership=true. Si el propietario nuevo crea un permiso nuevo, se envía una notificación por correo electrónico al propietario anterior para indicar que se transfirió la propiedad.

Cuando se transfiere un archivo, la función del propietario anterior pasa a una versión anterior: writer.

Cómo cambiar varios permisos con solicitudes por lotes

Te recomendamos usar solicitudes por lotes para modificar los permisos múltiples.

El siguiente es un ejemplo de cómo realizar una modificación del permiso por lotes con una biblioteca 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.
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;
        }
    }
}