Migrar do serviço de grupos para o serviço avançado de grupos do Cloud Identity

O serviço avançado do Cloud Identity Groups (CIG) oferece paridade de recursos à API Groups Service e pode ser usado no lugar dela.

Consulte os métodos auxiliares fornecidos para saber como alcançar recursos equivalentes com o CIG Advanced Service.

Configuração

Para usar o serviço avançado do CIG, primeiro ative-o no projeto de script.

Para encurtar algumas das assinaturas de método neste guia, definimos a seguinte variável:

const groups = CloudIdentityGroups.Groups;

Métodos GroupsApp

Os métodos auxiliares a seguir correspondem aos do serviço de grupos GroupsApp.

Neste guia, o termo grupo se refere a um recurso de grupo, e não a um objeto classe de grupo. Os recursos de grupo são objetos JavaScript que não têm métodos, mas podem ser usados no serviço avançado do CIG para recuperar informações semelhantes às dos objetos Classe de grupo.

getGroupByEmail

/**
 * Given a group's email, returns that group's resource
 *
 * @param {String} email: The email address to lookup a group by
 * @return {Group} group: The group resource associated with the email
 */
function groupsAppGetGroupByEmail(email) {
  // Retrieve the name ID of the group
  const groupName = groups.lookup({
    'groupKey.id': email,
    'groupKey.namespace': ''  // Optional for google groups, dynamic groups, and security groups
                              // Necessary for identity-mapped groups (see https://developers.google.com/cloud-search/docs/guides/identity-mapping)
  }).name;

  // Retrieve the group resource
  return groups.get(groupName);
}

getGroups

O método auxiliar a seguir retorna uma lista de recursos de associação. Acesse o campo group de um elemento para encontrar o ID do nome dele. Isso é útil para muitos métodos do CIG Advanced Service. Da mesma forma, acesse groupKey.id de um elemento para encontrar o e-mail dele.

/**
 * Retrieves all the membership relation resources to groups which you are a
 * direct member (or a pending member).
 *
 * @return {Array<MembershipRelation>} groups : List of direct memberships where
 * you are the member.
 */
function groupsAppGetGroups() {
  const myEmail = Session.getActiveUser().getEmail();
  let pageToken = '';
  let membershipList = [];

  do {
    const queryParams = {
      query:`member_key_id=='${myEmail}'`,
      pageToken:pageToken
    };
    const searchResult = groups.Memberships.searchDirectGroups('groups/-', queryParams);
    membershipList = membershipList.concat(searchResult.memberships);
    pageToken = searchResult.nextPageToken;
  } while (pageToken);

  return membershipList;
}

Métodos de grupo

Os métodos auxiliares a seguir correspondem aos do serviço de grupos Groups Class.

getEmail

/**
 * Gets a group's email address
 *
 * @param {Object} group: A group resource
 * @return {String} email: The email associated with the group resource.
 */
function getEmail(group) {
  return group.groupKey.id;
}

getGroups

O método a seguir usa Memberships.list, que vai buscar todas as associações ao grupo especificado. Isso pode incluir associações de usuários e grupos.

Para aproximar melhor o método getGroups do serviço de grupos, podemos filtrar as associações pelo Type delas. Para acessar esse campo, forneça um FULL View como um parâmetro de consulta para Memberships.list ou faça um Memberships.lookup individual para cada assinatura.

/**
 * Fetch a list of memberships with provided group as its parent
 *
 * @param {Group} group: A group resource
 * @return {Array<Membership>} membershipList: The memberships where the parent
 * is the provided group and member is a also a group.
 */
function getGroups(group) {
  let membershipList = [];
  let pageToken = '';

  do {
    // Fetch a page of memberships
    const queryParams = {
      view: 'FULL',
      pageToken: pageToken
    }
    const response = groups.Memberships.list(group.name, queryParams);

    // Filter non-group memberships
    const onlyGroupMemberships = response.memberships.filter(
      membership => membership.type == 'GROUP'
    );
    membershipList = membershipList.concat(onlyGroupMemberships);

    // Set up next page
    pageToken = response.nextPageToken;
  } while(pageToken);

  return membershipList;
}

getRole e getRoles

Embora o serviço Grupos possa ter retornado apenas a função de maior prioridade em getRole(), o campo roles em um recurso de associação contém um elemento separado para cada função em que o membro se qualifica (por exemplo: MEMBER, OWNER, ADMIN).

/**
 * Retrieve the membership roles of a member to a group.
 *
 * @param {Group} containingGroup: The group whom the member belongs to
 * @param {String} email: The email address associated with a member that
 * belongs to the containingGroup
 * @return {Array<Role>} roles: List of roles the member holds with respect to
 * the containingGroup.
 */
function getRoleWithEmail(containingGroup, email) {
  // First fetch the membership
  const membershipName = groups.Memberships.lookup(containingGroup.name, { 'memberKey.id': email }).name;
  const membership = groups.Memberships.get(membershipName);

  // Then retrieve the role
  return membership.roles;
}

/**
 * Retrieve the membership roles of a member to a group.
 *
 * @param {Group} containingGroup: The group resource whom the member belongs to
 * @param {User} user: The user associated with a member that belongs to the
 * containingGroup
 * @return {Array<Role>} roles: List of roles the member holds with respect to
 * the containingGroup
 */
function getRoleWithUser(containingGroup, user) {
  return getRoleWithEmail(containingGroup, user.getEmail());
}

/**
 * Retrieve the membership roles of a group of members to a group
 *
 * @param {Group} containingGroup: The group resource to which roles are
 * relevant
 * @param {Array<User>} users: List of users to fetch roles from
 * @return {Array<Array<Role>>} roles: A list where every element is a list of
 * roles of member to the containingGroup
 */
function getRoles(containingGroup, users) {
  let roles = [];
  for (const user of users) {
    roles.push(getRoleWithUser(containingGroup, user));
  }
  return roles;
}

getUsers

Assim como na nossa abordagem em getGroups, podemos buscar as associações de um grupo com Memberships.list e filtrar os resultados para manter apenas o Type de destino.

/**
 * Given a group, retrieve its direct members and banned members of the group
 * that have a known corresponding Google Account.
 *
 * @param {Group} group: The group Resource whom the users being queried belong
 * to
 * @return {Array<String>} users: A list of emails associated with members of
 * the given group
 */
function getUsers(group) {
  let userList = [];
  let pageToken = '';

  do {
    // Fetch a page of memberships from the group
    const queryParams = {
      view: 'FULL',
      pageToken: pageToken
    }
    const listResponse = groups.Memberships.list(group.name, queryParams);

    // Filter non-users and keep member emails
    const users = listResponse.memberships
      .filter(membership => membership.type == 'USER')
      .map(membership => membership.preferredMemberKey.id);
    userList = userList.concat(users);

    // Prepare next page
    pageToken = listResponse.nextPageToken;
  } while (pageToken);

  return userList;
}

hasGroup e hasUser

Os serviços de grupos hasGroup e hasUser confirmam se uma entidade é participante de um determinado grupo. Como um grupo e um usuário podem ser representados por um endereço de e-mail, o método a seguir pode ser usado para confirmar se um deles pertence a um determinado grupo.

/**
 * Tests if the given email has an associated direct member to the given group.
 *
 * @param {Group} group: Group resource to which the entity is being checked as
 * a member
 * @param {String} email: Email that can represent a Group or User entity
 * @return {Boolean} isMember: Whether the entity is a direct member to the
 * group or not
 */
function checkDirectGroupMembership(group, email) {
  try {
    groups.Memberships.lookup(group.name, {'memberKey.id': email});

  } catch(e) {
    // Log failure if exception is not related to membership existence
    if (!e.message.includes('Membership does not exist.')) {
      console.error(e);
    }
    return false;
  }
  return true;
}