Example #1
0
def bulk_is_invitable(emails):
    '''gam <users> check isinvitable'''
    def _invitation_result(request_id, response, _):
        if response.get('isInvitableUser'):
            rows.append({'invitableUsers': request_id})

    svc = gapi_cloudidentity.build('cloudidentity_beta')
    customer = _get_customerid()
    todrive = False
    #batch_size = 1000
    #ebatch = svc.new_batch_http_request(callback=_invitation_result)
    rows = []
    throw_reasons = [gapi_errors.ErrorReason.FOUR_O_THREE]
    for email in emails:
        encoded_email = quote_plus(email)
        name = f'{customer}/userinvitations/{encoded_email}'
        endpoint = svc.customers().userinvitations()
        #if len(ebatch._order) == batch_size:
        #    ebatch.execute()
        #    ebatch = svc.new_batch_http_request(callback=_invitation_result)
        #req = endpoint.isInvitableUser(name=name)
        #ebatch.add(req, request_id=email)
        try:
            result = gapi.call(endpoint,
                               'isInvitableUser',
                               throw_reasons=throw_reasons,
                               name=name)
        except googleapiclient.errors.HttpError:
            continue
        if result.get('isInvitableUser'):
            rows.append({'invitableUsers': email})
    #ebatch.execute()
    titles = ['invitableUsers']
    display.write_csv_file(rows, titles, 'Invitable Users', todrive)
Example #2
0
def print_():
    '''gam print userinvitations'''
    svc = gapi_cloudidentity.build('cloudidentity_beta')
    customer = _get_customerid()
    todrive = False
    titles = []
    rows = []
    filter_ = None
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'filter':
            filter_ = sys.argv[i + 1]
            i += 2
        elif myarg == 'todrive':
            todrive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print userinvitations')
    invitations = gapi.get_all_pages(svc.customers().userinvitations(),
                                     'list',
                                     'userInvitations',
                                     parent=customer,
                                     filter=filter_)
    for invitation in invitations:
        invitation['name'] = _reduce_name(invitation['name'])
        row = {}
        for key, val in invitation.items():
            if key not in titles:
                titles.append(key)
            row[key] = val
        rows.append(row)
    display.write_csv_file(rows, titles, 'User Invitations', todrive)
Example #3
0
def info():
    ci = gapi_cloudidentity.build('cloudidentity_beta')
    group = gam.normalizeEmailAddressOrUID(sys.argv[3])
    getUsers = True
    showJoinDate = True
    showUpdateDate = False
    showMemberTree = False
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'nousers':
            getUsers = False
            i += 1
        elif myarg == 'nojoindate':
            showJoinDate = False
            i += 1
        elif myarg == 'showupdatedate':
            showUpdateDate = True
            i += 1
        elif myarg == 'membertree':
            showMemberTree = True
            i += 1
        else:
            controlflow.invalid_argument_exit(myarg, 'gam info cigroup')
    name = group_email_to_id(ci, group)
    basic_info = gapi.call(ci.groups(), 'get', name=name)
    display.print_json(basic_info)
    if getUsers and not showMemberTree:
        if not showJoinDate and not showUpdateDate:
            view = 'BASIC'
            pageSize = 1000
        else:
            view = 'FULL'
            pageSize = 500
        members = gapi.get_all_pages(ci.groups().memberships(),
                                     'list',
                                     'memberships',
                                     parent=name,
                                     fields='*',
                                     pageSize=pageSize,
                                     view=view)
        print(' Members:')
        for member in members:
            role = get_single_role(member.get('roles', [])).lower()
            email = member.get('memberKey', {}).get('id')
            member_type = member.get('type', 'USER').lower()
            jc_string = ''
            if showJoinDate:
                joined = member.get('createTime', 'Unknown')
                jc_string += f'  joined {joined}'
            if showUpdateDate:
                updated = member.get('updateTime', 'Unknown')
                jc_string += f'  updated {updated}'
            print(f'  {role}: {email} ({member_type}){jc_string}')
        print(f'Total {len(members)} users in group')
    elif showMemberTree:
        print(' Membership Tree:')
        cached_group_members = {}
        print_member_tree(ci, name, cached_group_members, 2, True)
Example #4
0
def get_membership_graph(member):
    ci = gapi_cloudidentity.build('cloudidentity_beta')
    query = f"member_key_id == '{member}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels"
    result = gapi.call(ci.groups().memberships(),
                     'getMembershipGraph',
                     parent='groups/-',
                     query=query)
    return result.get('response')
Example #5
0
def _generic_get(get_type):
    '''generic function to call read data APIs'''
    svc = gapi_cloudidentity.build('cloudidentity_beta')
    customer = _get_customerid()
    email = sys.argv[3].lower()
    encoded_email = quote_plus(email)
    name = f'{customer}/userinvitations/{encoded_email}'
    result = gapi.call(svc.customers().userinvitations(), get_type, name=name)
    if 'name' in result:
        result['name'] = _reduce_name(result['name'])
    display.print_json(result)
Example #6
0
def create():
    ci = gapi_cloudidentity.build('cloudidentity_beta')
    initialGroupConfig = 'EMPTY'
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    body = {
        'groupKey': {
            'id': gam.normalizeEmailAddressOrUID(sys.argv[3], noUid=True)
        },
        'parent': parent,
        'labels': {
            'cloudidentity.googleapis.com/groups.discussion_forum': ''
        },
    }
    i = 4
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'name':
            body['displayName'] = sys.argv[i + 1]
            i += 2
        elif myarg == 'description':
            body['description'] = sys.argv[i + 1]
            i += 2
        elif myarg in ['alias', 'aliases']:
            # As of 2020/06/25 this doesn't work (yet?)
            aliases = sys.argv[i + 1].split(' ')
            body['additionalGroupKeys'] = []
            for alias in aliases:
                body['additionalGroupKeys'].append({'id': alias})
            i += 2
        elif myarg in ['dynamic']:
            # As of 2020/06/25 this doesn't work (yet?)
            body['dynamicGroupMetadata'] = {
                'queries': [{
                    'query': sys.argv[i + 1],
                    'resourceType': 'USER'
                }]
            }
            i += 2
        elif myarg in ['makeowner']:
            initialGroupConfig = 'WITH_INITIAL_OWNER'
            i += 1
        else:
            print('should not get here')
            sys.exit(5)
    print(f'Creating group {body["groupKey"]["id"]}')
    gapi.call(ci.groups(),
              'create',
              initialGroupConfig=initialGroupConfig,
              body=body)
Example #7
0
def _generic_action(action):
    '''generic function to call actionable APIs'''
    svc = gapi_cloudidentity.build('cloudidentity_beta')
    customer = _get_customerid()
    email = sys.argv[3].lower()
    encoded_email = quote_plus(email)
    name = f'{customer}/userinvitations/{encoded_email}'
    action_map = {'cancel': 'Cancelling', 'send': 'Sending'}
    print_action = action_map[action]
    print(f'{print_action} user invitation...')
    result = gapi.call(svc.customers().userinvitations(), action, name=name)
    name = result.get('response', {}).get('name')
    if name:
        result['response']['name'] = _reduce_name(name)
    display.print_json(result)
Example #8
0
def info_member():
    ci = gapi_cloudidentity.build()
    member = gam.normalizeEmailAddressOrUID(sys.argv[3])
    group = gam.normalizeEmailAddressOrUID(sys.argv[4])
    group_name = gapi.call(ci.groups(),
                           'lookup',
                           groupKey_id=group,
                           fields='name').get('name')
    member_name = gapi.call(ci.groups().memberships(),
                            'lookup',
                            parent=group_name,
                            memberKey_id=member,
                            fields='name').get('name')
    member_details = gapi.call(ci.groups().memberships(),
                               'get',
                               name=member_name)
    display.print_json(member_details)
Example #9
0
def _get_groups_list(ci=None, member=None, parent=None):
    if not ci:
        ci = gapi_cloudidentity.build()
    if not parent:
        gapi_directory_customer.setTrueCustomerId()
        parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    gam.printGettingAllItems('Groups', member)
    page_message = gapi.got_total_items_first_last_msg('Groups')
    if member:
        fields = 'nextPageToken,memberships(groupKey(id),relationType)'
        try:
            groups_to_get = gapi.get_all_pages(
                ci.groups().memberships(),
                'searchTransitiveGroups',
                'memberships',
                throw_reasons=[gapi_errors.ErrorReason.FOUR_O_O],
                message_attribute=['groupKey', 'id'],
                page_message=page_message,
                parent='groups/-',
                query=member,
                pageSize=1000,
                fields=fields)
        except googleapiclient.errors.HttpError:
            controlflow.system_error_exit(
                2, 'enterprisemember requires Enterprise license')
        return [
            group['groupKey']['id'] for group in groups_to_get
            if group['relationType'] == 'DIRECT'
        ]
    else:
        groups_to_get = gapi.get_all_pages(
            ci.groups(),
            'list',
            'groups',
            message_attribute=['groupKey', 'id'],
            page_message=page_message,
            parent=parent,
            view='BASIC',
            pageSize=1000,
            fields='nextPageToken,groups(groupKey(id))')
        return [group['groupKey']['id'] for group in groups_to_get]
Example #10
0
def delete():
    ci = gapi_cloudidentity.build()
    group = sys.argv[3]
    name = group_email_to_id(ci, group)
    print(f'Deleting group {group}')
    gapi.call(ci.groups(), 'delete', name=name)
Example #11
0
def update():

    # Convert [email protected] to [email protected]; eliminate periods in name for [email protected]
    def _cleanConsumerAddress(emailAddress, mapCleanToOriginal):
        atLoc = emailAddress.find('@')
        if atLoc > 0:
            if emailAddress[atLoc + 1:] in ['gmail.com', 'googlemail.com']:
                cleanEmailAddress = emailAddress[:atLoc].replace(
                    '.', '') + '@gmail.com'
                if cleanEmailAddress != emailAddress:
                    mapCleanToOriginal[cleanEmailAddress] = emailAddress
                    return cleanEmailAddress
        return emailAddress

    def _getRoleAndUsers():
        checkSuspended = None
        role = None
        i = 5
        if sys.argv[i].lower() in GROUP_ROLES_MAP:
            role = GROUP_ROLES_MAP[sys.argv[i].lower()]
            i += 1
        if sys.argv[i].lower() in ['suspended', 'notsuspended']:
            checkSuspended = sys.argv[i].lower() == 'suspended'
            i += 1
        if sys.argv[i].lower() in usergroup_types:
            users_email = gam.getUsersToModify(entity_type=sys.argv[i].lower(),
                                               entity=sys.argv[i + 1],
                                               checkSuspended=checkSuspended,
                                               groupUserMembersOnly=False)
        else:
            users_email = [
                gam.normalizeEmailAddressOrUID(sys.argv[i],
                                               checkForCustomerId=True)
            ]
        return (role, users_email)

    ci = gapi_cloudidentity.build()
    group = sys.argv[3]
    myarg = sys.argv[4].lower()
    items = []
    if myarg in UPDATE_GROUP_SUBCMDS:
        group = gam.normalizeEmailAddressOrUID(group)
        if group.startswith('groups/'):
            parent = group
        else:
            parent = group_email_to_id(ci, group)
        if not parent:
            return
        if myarg == 'add':
            role, users_email = _getRoleAndUsers()
            if not role:
                role = ROLE_MEMBER
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will add {len(users_email)} {role}s.\n')
                for user_email in users_email:
                    item = [
                        'gam', 'update', 'cigroup', f'id:{parent}', 'add',
                        role, user_email
                    ]
                    items.append(item)
            elif len(users_email) > 0:
                body = {
                    'memberKey': {
                        'id': users_email[0]
                    },
                    'roles': [{
                        'name': ROLE_MEMBER
                    }]
                }
                if role != ROLE_MEMBER:
                    body['roles'].append({'name': role})
                add_text = [f'as {role}']
                for i in range(2):
                    try:
                        gapi.call(
                            ci.groups().memberships(),
                            'create',
                            throw_reasons=[
                                gapi_errors.ErrorReason.FOUR_O_NINE,
                                gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                gapi_errors.ErrorReason.RESOURCE_NOT_FOUND,
                                gapi_errors.ErrorReason.INVALID_MEMBER,
                                gapi_errors.ErrorReason.
                                CYCLIC_MEMBERSHIPS_NOT_ALLOWED
                            ],
                            parent=parent,
                            body=body)
                        print(
                            f' Group: {group}, {users_email[0]} Added {" ".join(add_text)}'
                        )
                        break
                    except (gapi_errors.GapiMemberNotFoundError,
                            gapi_errors.GapiResourceNotFoundError,
                            gapi_errors.GapiInvalidMemberError,
                            gapi_errors.GapiCyclicMembershipsNotAllowedError
                            ) as e:
                        print(
                            f' Group: {group}, {users_email[0]} Add {" ".join(add_text)} Failed: {str(e)}'
                        )
                        break
        elif myarg == 'sync':
            syncMembersSet = set()
            syncMembersMap = {}
            role, users_email = _getRoleAndUsers()
            for user_email in users_email:
                if user_email in ('*', GC_Values[GC_CUSTOMER_ID]):
                    syncMembersSet.add(GC_Values[GC_CUSTOMER_ID])
                else:
                    syncMembersSet.add(
                        _cleanConsumerAddress(user_email.lower(),
                                              syncMembersMap))
            currentMembersSet = set()
            currentMembersMap = {}
            for current_email in gam.getUsersToModify(
                    entity_type='cigroup',
                    entity=group,
                    member_type=role,
                    groupUserMembersOnly=False):
                if current_email == GC_Values[GC_CUSTOMER_ID]:
                    currentMembersSet.add(current_email)
                else:
                    currentMembersSet.add(
                        _cleanConsumerAddress(current_email.lower(),
                                              currentMembersMap))
            to_add = [
                syncMembersMap.get(emailAddress, emailAddress)
                for emailAddress in syncMembersSet - currentMembersSet
            ]
            to_remove = [
                currentMembersMap.get(emailAddress, emailAddress)
                for emailAddress in currentMembersSet - syncMembersSet
            ]
            sys.stderr.write(
                f'Group: {group}, Will add {len(to_add)} and remove {len(to_remove)} {role}s.\n'
            )
            for user in to_add:
                item = [
                    'gam', 'update', 'cigroup', f'id:{parent}', 'add', role,
                    user
                ]
                items.append(item)
            for user in to_remove:
                items.append([
                    'gam', 'update', 'cigroup', f'id:{parent}', 'remove', user
                ])
        elif myarg in ['delete', 'remove']:
            _, users_email = _getRoleAndUsers()
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will remove {len(users_email)} emails.\n'
                )
                for user_email in users_email:
                    items.append([
                        'gam', 'update', 'cigroup', f'id:{parent}', 'remove',
                        user_email
                    ])
            elif len(users_email) == 1:
                name = membership_email_to_id(ci, parent, users_email[0])
                try:
                    gapi.call(ci.groups().memberships(),
                              'delete',
                              throw_reasons=[
                                  gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                  gapi_errors.ErrorReason.INVALID_MEMBER
                              ],
                              name=name)
                    print(f' Group: {group}, {users_email[0]} Removed')
                except (gapi_errors.GapiMemberNotFoundError,
                        gapi_errors.GapiInvalidMemberError) as e:
                    print(
                        f' Group: {group}, {users_email[0]} Remove Failed: {str(e)}'
                    )
        elif myarg == 'update':
            role, users_email = _getRoleAndUsers()
            if not role:
                role = ROLE_MEMBER
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will update {len(users_email)} {role}s.\n'
                )
                for user_email in users_email:
                    item = [
                        'gam', 'update', 'cigroup', f'id:{parent}', 'update',
                        role, user_email
                    ]
                    items.append(item)
            elif len(users_email) > 0:
                name = membership_email_to_id(ci, parent, users_email[0])
                addRoles = []
                removeRoles = []
                new_role = {'role': role}
                current_roles = gapi.call(ci.groups().memberships(),
                                          'get',
                                          name=name,
                                          fields='roles').get('roles', [])
                current_roles = [role['name'] for role in current_roles]
                for crole in current_roles:
                    if crole != ROLE_MEMBER and crole != role:
                        removeRoles.append(crole)
                if role not in current_roles:
                    addRoles.append({'name': role})
                bodys = []
                if addRoles:
                    bodys.append({'addRoles': addRoles})
                if removeRoles:
                    bodys.append({'removeRoles': removeRoles})
                for body in bodys:
                    try:
                        gapi.call(ci.groups().memberships(),
                                  'modifyMembershipRoles',
                                  throw_reasons=[
                                      gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                      gapi_errors.ErrorReason.INVALID_MEMBER
                                  ],
                                  name=name,
                                  body=body)
                    except (gapi_errors.GapiMemberNotFoundError,
                            gapi_errors.GapiInvalidMemberError) as e:
                        print(
                            f' Group: {group}, {users_email[0]} Update to {role} Failed: {str(e)}'
                        )
                        break
                print(f' Group: {group}, {users_email[0]} Updated to {role}')

        else:  # clear
            roles = []
            i = 5
            while i < len(sys.argv):
                myarg = sys.argv[i].lower()
                if myarg.upper() in [ROLE_OWNER, ROLE_MANAGER, ROLE_MEMBER]:
                    roles.append(myarg.upper())
                    i += 1
                else:
                    controlflow.invalid_argument_exit(
                        sys.argv[i], 'gam update cigroup clear')
            if not roles:
                roles = [ROLE_MEMBER]
            group = gam.normalizeEmailAddressOrUID(group)
            member_type_message = f'{",".join(roles).lower()}s'
            sys.stderr.write(
                f'Getting {member_type_message} of {group} (may take some time for large groups)...\n'
            )
            page_message = gapi.got_total_items_msg(f'{member_type_message}',
                                                    '...')
            try:
                result = gapi.get_all_pages(
                    ci.groups().memberships(),
                    'list',
                    'memberships',
                    page_message=page_message,
                    throw_reasons=gapi_errors.MEMBERS_THROW_REASONS,
                    parent=parent,
                    fields='nextPageToken,memberships(memberKey,roles)')
                result = filter_members_to_roles(result, roles)
                if not result:
                    print('Group already has 0 members')
                    return
                users_email = [member['memberKey']['id'] for member in result]
                sys.stderr.write(
                    f'Group: {group}, Will remove {len(users_email)} {", ".join(roles).lower()}s.\n'
                )
                for user_email in users_email:
                    items.append([
                        'gam', 'update', 'cigroup', group, 'remove', user_email
                    ])
            except (gapi_errors.GapiGroupNotFoundError,
                    gapi_errors.GapiDomainNotFoundError,
                    gapi_errors.GapiInvalidError,
                    gapi_errors.GapiForbiddenError):
                gam.entityUnknownWarning('Group', group, 0, 0)
        if items:
            gam.run_batch(items)
    else:
        i = 4
        body = {}
        while i < len(sys.argv):
            myarg = sys.argv[i].lower().replace('_', '')
            if myarg == 'name':
                body['displayName'] = sys.argv[i + 1]
                i += 2
            elif myarg == 'description':
                body['description'] = sys.argv[i + 1]
                i += 2
            else:
                controlflow.invalid_argument_exit(sys.argv[i],
                                                  'gam update cigroup')
        updateMask = ','.join(body.keys())
        name = group_email_to_id(ci, group)
        print(f'Updating group {group}')
        gapi.call(ci.groups(),
                  'patch',
                  updateMask=updateMask,
                  name=name,
                  body=body)
Example #12
0
def print_members():
    ci = gapi_cloudidentity.build()
    todrive = False
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    roles = []
    titles = ['group']
    csvRows = []
    groups_to_get = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in ['role', 'roles']:
            for role in sys.argv[i + 1].lower().replace(',', ' ').split():
                if role in GROUP_ROLES_MAP:
                    roles.append(GROUP_ROLES_MAP[role])
                else:
                    controlflow.system_error_exit(
                        2,
                        f'{role} is not a valid role for "gam print group-members {myarg}"'
                    )
            i += 2
        elif myarg in ['cigroup', 'cigroups']:
            group_email = gam.normalizeEmailAddressOrUID(sys.argv[i + 1])
            groups_to_get = [group_email]
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print cigroup-members')
    if not groups_to_get:
        gam.printGettingAllItems('Groups', None)
        page_message = gapi.got_total_items_first_last_msg('Groups')
        groups_to_get = gapi.get_all_pages(
            ci.groups(),
            'list',
            'groups',
            message_attribute=['groupKey', 'id'],
            page_message=page_message,
            parent=parent,
            view='BASIC',
            pageSize=1000,
            fields='nextPageToken,groups(groupKey(id))')
        groups_to_get = [group['groupKey']['id'] for group in groups_to_get]
    i = 0
    count = len(groups_to_get)
    for group_email in groups_to_get:
        i += 1

        sys.stderr.write(
            f'Getting members for {group_email}{gam.currentCountNL(i, count)}')
        group_id = group_email_to_id(ci, group_email)
        print(f'Getting members of cigroup {group_email}...')
        page_message = f' {gapi.got_total_items_first_last_msg("Members")}'
        group_members = gapi.get_all_pages(
            ci.groups().memberships(),
            'list',
            'memberships',
            soft_errors=True,
            parent=group_id,
            view='FULL',
            pageSize=500,
            page_message=page_message,
            message_attribute=['memberKey', 'id'])
        #fields='nextPageToken,memberships(memberKey,roles,createTime,updateTime)')
        if roles:
            group_members = filter_members_to_roles(group_members, roles)
        for member in group_members:
            # reduce role to a single value
            member['role'] = get_single_role(member.pop('roles'))
            member = utils.flatten_json(member)
            for title in member:
                if title not in titles:
                    titles.append(title)
            member['group'] = group_email
            csvRows.append(member)
    display.write_csv_file(csvRows, titles, 'Group Members', todrive)
Example #13
0
def print_():
    ci = gapi_cloudidentity.build()
    i = 3
    members = membersCountOnly = managers = managersCountOnly = owners = ownersCountOnly = False
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    aliasDelimiter = ' '
    memberDelimiter = '\n'
    todrive = False
    titles = []
    csvRows = []
    roles = []
    sortHeaders = False
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg == 'delimiter':
            aliasDelimiter = memberDelimiter = sys.argv[i + 1]
            i += 2
        elif myarg == 'sortheaders':
            sortHeaders = True
            i += 1
        elif myarg in ['members', 'memberscount']:
            roles.append(ROLE_MEMBER)
            members = True
            if myarg == 'memberscount':
                membersCountOnly = True
            i += 1
        elif myarg in ['owners', 'ownerscount']:
            roles.append(ROLE_OWNER)
            owners = True
            if myarg == 'ownerscount':
                ownersCountOnly = True
            i += 1
        elif myarg in ['managers', 'managerscount']:
            roles.append(ROLE_MANAGER)
            managers = True
            if myarg == 'managerscount':
                managersCountOnly = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print cigroups')
    if roles:
        if members:
            display.add_titles_to_csv_file([
                'MembersCount',
            ], titles)
            if not membersCountOnly:
                display.add_titles_to_csv_file([
                    'Members',
                ], titles)
        if managers:
            display.add_titles_to_csv_file([
                'ManagersCount',
            ], titles)
            if not managersCountOnly:
                display.add_titles_to_csv_file([
                    'Managers',
                ], titles)
        if owners:
            display.add_titles_to_csv_file([
                'OwnersCount',
            ], titles)
            if not ownersCountOnly:
                display.add_titles_to_csv_file([
                    'Owners',
                ], titles)
    gam.printGettingAllItems('Groups', None)
    page_message = gapi.got_total_items_first_last_msg('Groups')
    entityList = gapi.get_all_pages(ci.groups(),
                                    'list',
                                    'groups',
                                    page_message=page_message,
                                    message_attribute=['groupKey', 'id'],
                                    parent=parent,
                                    srcview='FULL',
                                    pageSize=500)
    i = 0
    count = len(entityList)
    for groupEntity in entityList:
        i += 1
        groupEmail = groupEntity['groupKey']['id']
        group = utils.flatten_json(groupEntity)
        for a_key in group:
            if a_key not in titles:
                titles.append(a_key)
        groupKey_id = groupEntity['name']
        if roles:
            sys.stderr.write(
                f' Getting {roles} for {groupEmail}{gam.currentCountNL(i, count)}'
            )
            page_message = gapi.got_total_items_first_last_msg('Members')
            validRoles, listRoles, listFields = gam._getRoleVerification(
                roles, 'nextPageToken,members(email,id,role)')
            groupMembers = gapi.get_all_pages(ci.groups().memberships(),
                                              'list',
                                              'memberships',
                                              page_message=page_message,
                                              message_attribute='email',
                                              soft_errors=True,
                                              groupKey_id=groupKey_id,
                                              view='BASIC')
            if members:
                membersList = []
                membersCount = 0
            if managers:
                managersList = []
                managersCount = 0
            if owners:
                ownersList = []
                ownersCount = 0
            for member in groupMembers:
                member_email = member['memberKey']['id']
                role = get_single_role(member.get('roles'))
                if not validRoles or role in validRoles:
                    if role == ROLE_MEMBER:
                        if members:
                            membersCount += 1
                            if not membersCountOnly:
                                membersList.append(member_email)
                    elif role == ROLE_MANAGER:
                        if managers:
                            managersCount += 1
                            if not managersCountOnly:
                                managersList.append(member_email)
                    elif role == ROLE_OWNER:
                        if owners:
                            ownersCount += 1
                            if not ownersCountOnly:
                                ownersList.append(member_email)
                    elif members:
                        membersCount += 1
                        if not membersCountOnly:
                            membersList.append(member_email)
            if members:
                group['MembersCount'] = membersCount
                if not membersCountOnly:
                    group['Members'] = memberDelimiter.join(membersList)
            if managers:
                group['ManagersCount'] = managersCount
                if not managersCountOnly:
                    group['Managers'] = memberDelimiter.join(managersList)
            if owners:
                group['OwnersCount'] = ownersCount
                if not ownersCountOnly:
                    group['Owners'] = memberDelimiter.join(ownersList)
        csvRows.append(group)
    if sortHeaders:
        display.sort_csv_titles([
            'Email',
        ], titles)
    display.write_csv_file(csvRows, titles, 'Groups', todrive)
Example #14
0
def print_members():
    ci = gapi_cloudidentity.build('cloudidentity_beta')
    todrive = False
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    usemember = None
    roles = []
    titles = ['group']
    csvRows = []
    groups_to_get = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in ['role', 'roles']:
            for role in sys.argv[i + 1].lower().replace(',', ' ').split():
                if role in GROUP_ROLES_MAP:
                    roles.append(GROUP_ROLES_MAP[role])
                else:
                    controlflow.system_error_exit(
                        2,
                        f'{role} is not a valid role for "gam print group-members {myarg}"'
                    )
            i += 2
        elif myarg == 'enterprisemember':
            member = gam.convertUIDtoEmailAddress(
                sys.argv[i + 1], email_types=['user', 'group'])
            usemember = f"member_key_id == '{member}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels"
            i += 2
        elif myarg in ['cigroup', 'cigroups']:
            group_email = gam.normalizeEmailAddressOrUID(sys.argv[i + 1])
            groups_to_get = [group_email]
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print cigroup-members')
    if not groups_to_get:
        gam.printGettingAllItems('Groups', usemember)
        page_message = gapi.got_total_items_first_last_msg('Groups')
        if usemember:
            try:
                groups_to_get = gapi.get_all_pages(
                    ci.groups().memberships(),
                    'searchTransitiveGroups',
                    'memberships',
                    throw_reasons=[gapi_errors.ErrorReason.FOUR_O_O],
                    message_attribute=['groupKey', 'id'],
                    page_message=page_message,
                    parent='groups/-',
                    query=usemember,
                    pageSize=1000,
                    fields=
                    'nextPageToken,memberships(groupKey(id),relationType)')
            except googleapiclient.errors.HttpError:
                controlflow.system_error_exit(
                    2, f'enterprisemember requires Enterprise license')
            groups_to_get = [
                group['groupKey']['id'] for group in groups_to_get
                if group['relationType'] == 'DIRECT'
            ]
        else:
            groups_to_get = gapi.get_all_pages(
                ci.groups(),
                'list',
                'groups',
                message_attribute=['groupKey', 'id'],
                page_message=page_message,
                parent=parent,
                view='BASIC',
                pageSize=1000,
                fields='nextPageToken,groups(groupKey(id))')
            groups_to_get = [
                group['groupKey']['id'] for group in groups_to_get
            ]
    i = 0
    count = len(groups_to_get)
    for group_email in groups_to_get:
        i += 1

        sys.stderr.write(
            f'Getting members for {group_email}{gam.currentCountNL(i, count)}')
        group_id = group_email_to_id(ci, group_email)
        print(f'Getting members of cigroup {group_email}...')
        page_message = f' {gapi.got_total_items_first_last_msg("Members")}'
        group_members = gapi.get_all_pages(
            ci.groups().memberships(),
            'list',
            'memberships',
            soft_errors=True,
            parent=group_id,
            view='FULL',
            pageSize=500,
            page_message=page_message,
            message_attribute=['memberKey', 'id'])
        #fields='nextPageToken,memberships(memberKey,roles,createTime,updateTime)')
        if roles:
            group_members = filter_members_to_roles(group_members, roles)
        for member in group_members:
            # reduce role to a single value
            member['role'] = get_single_role(member.pop('roles'))
            member = utils.flatten_json(member)
            for title in member:
                if title not in titles:
                    titles.append(title)
            member['group'] = group_email
            csvRows.append(member)
    display.write_csv_file(csvRows, titles, 'Group Members', todrive)
Example #15
0
def print_():
    ci = gapi_cloudidentity.build('cloudidentity_beta')
    i = 3
    members = membersCountOnly = managers = managersCountOnly = owners = ownersCountOnly = False
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    usemember = None
    memberDelimiter = '\n'
    todrive = False
    titles = []
    csvRows = []
    roles = []
    sortHeaders = False
    while i < len(sys.argv):
        myarg = sys.argv[i].lower()
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg == 'enterprisemember':
            member = gam.convertUIDtoEmailAddress(
                sys.argv[i + 1], email_types=['user', 'group'])
            usemember = f"member_key_id == '{member}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels"
            i += 2
        elif myarg == 'delimiter':
            memberDelimiter = sys.argv[i + 1]
            i += 2
        elif myarg == 'sortheaders':
            sortHeaders = True
            i += 1
        elif myarg in ['members', 'memberscount']:
            roles.append(ROLE_MEMBER)
            members = True
            if myarg == 'memberscount':
                membersCountOnly = True
            i += 1
        elif myarg in ['owners', 'ownerscount']:
            roles.append(ROLE_OWNER)
            owners = True
            if myarg == 'ownerscount':
                ownersCountOnly = True
            i += 1
        elif myarg in ['managers', 'managerscount']:
            roles.append(ROLE_MANAGER)
            managers = True
            if myarg == 'managerscount':
                managersCountOnly = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print cigroups')
    if roles:
        if members:
            display.add_titles_to_csv_file([
                'MembersCount',
            ], titles)
            if not membersCountOnly:
                display.add_titles_to_csv_file([
                    'Members',
                ], titles)
        if managers:
            display.add_titles_to_csv_file([
                'ManagersCount',
            ], titles)
            if not managersCountOnly:
                display.add_titles_to_csv_file([
                    'Managers',
                ], titles)
        if owners:
            display.add_titles_to_csv_file([
                'OwnersCount',
            ], titles)
            if not ownersCountOnly:
                display.add_titles_to_csv_file([
                    'Owners',
                ], titles)
    gam.printGettingAllItems('Groups', usemember)
    page_message = gapi.got_total_items_first_last_msg('Groups')
    if usemember:
        try:
            result = gapi.get_all_pages(
                ci.groups().memberships(),
                'searchTransitiveGroups',
                'memberships',
                throw_reasons=[gapi_errors.ErrorReason.FOUR_O_O],
                page_message=page_message,
                message_attribute=['groupKey', 'id'],
                parent='groups/-',
                query=usemember,
                fields=
                'nextPageToken,memberships(group,groupKey(id),relationType)',
                pageSize=1000)
        except googleapiclient.errors.HttpError:
            controlflow.system_error_exit(
                2, f'enterprisemember requires Enterprise license')
        entityList = []
        for entity in result:
            if entity['relationType'] == 'DIRECT':
                entityList.append(
                    gapi.call(ci.groups(), 'get', name=entity['group']))
    else:
        entityList = gapi.get_all_pages(ci.groups(),
                                        'list',
                                        'groups',
                                        page_message=page_message,
                                        message_attribute=['groupKey', 'id'],
                                        parent=parent,
                                        view='FULL',
                                        pageSize=500)
    i = 0
    count = len(entityList)
    for groupEntity in entityList:
        i += 1
        groupEmail = groupEntity['groupKey']['id']
        for k, v in iter(groupEntity.pop('labels', {}).items()):
            if v == '':
                groupEntity[f'labels.{k}'] = True
            else:
                groupEntity[f'labels.{k}'] = v
        group = utils.flatten_json(groupEntity)
        for a_key in group:
            if a_key not in titles:
                titles.append(a_key)
        groupKey_id = groupEntity['name']
        if roles:
            sys.stderr.write(
                f' Getting {roles} for {groupEmail}{gam.currentCountNL(i, count)}'
            )
            page_message = gapi.got_total_items_first_last_msg('Members')
            validRoles, _, _ = gam._getRoleVerification(
                '.'.join(roles), 'nextPageToken,members(email,id,role)')
            groupMembers = gapi.get_all_pages(
                ci.groups().memberships(),
                'list',
                'memberships',
                page_message=page_message,
                message_attribute=['memberKey', 'id'],
                soft_errors=True,
                parent=groupKey_id,
                view='BASIC')
            if members:
                membersList = []
                membersCount = 0
            if managers:
                managersList = []
                managersCount = 0
            if owners:
                ownersList = []
                ownersCount = 0
            for member in groupMembers:
                member_email = member['memberKey']['id']
                role = get_single_role(member.get('roles'))
                if not validRoles or role in validRoles:
                    if role == ROLE_MEMBER:
                        if members:
                            membersCount += 1
                            if not membersCountOnly:
                                membersList.append(member_email)
                    elif role == ROLE_MANAGER:
                        if managers:
                            managersCount += 1
                            if not managersCountOnly:
                                managersList.append(member_email)
                    elif role == ROLE_OWNER:
                        if owners:
                            ownersCount += 1
                            if not ownersCountOnly:
                                ownersList.append(member_email)
                    elif members:
                        membersCount += 1
                        if not membersCountOnly:
                            membersList.append(member_email)
            if members:
                group['MembersCount'] = membersCount
                if not membersCountOnly:
                    group['Members'] = memberDelimiter.join(membersList)
            if managers:
                group['ManagersCount'] = managersCount
                if not managersCountOnly:
                    group['Managers'] = memberDelimiter.join(managersList)
            if owners:
                group['OwnersCount'] = ownersCount
                if not ownersCountOnly:
                    group['Owners'] = memberDelimiter.join(ownersList)
        csvRows.append(group)
    if sortHeaders:
        display.sort_csv_titles(['name', 'groupKey.id'], titles)
    display.write_csv_file(csvRows, titles, 'Groups', todrive)
Example #16
0
def print_():
    '''gam print userinvitations'''
    svc = gapi_cloudidentity.build('cloudidentity_beta')
    customer = _get_customerid()
    todrive = False
    titles = ['name', 'state', 'updateTime']
    rows = []
    filter_ = None
    orderByList = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'state':
            state = sys.argv[i + 1].lower().replace('_', '')
            if state in USERINVITATION_STATE_CHOICES_MAP:
                filter_ = f"state=='{USERINVITATION_STATE_CHOICES_MAP[state]}'"
            else:
                controlflow.expected_argument_exit(
                    'state', ', '.join(USERINVITATION_STATE_CHOICES_MAP),
                    state)
            i += 2
        elif myarg == 'orderby':
            fieldName = sys.argv[i + 1].lower()
            i += 2
            if fieldName in USERINVITATION_ORDERBY_CHOICES_MAP:
                fieldName = USERINVITATION_ORDERBY_CHOICES_MAP[fieldName]
                orderBy = ''
                if i < len(sys.argv):
                    orderBy = sys.argv[i].lower()
                    if orderBy in SORTORDER_CHOICES_MAP:
                        orderBy = SORTORDER_CHOICES_MAP[orderBy]
                        i += 1
                if orderBy != 'DESCENDING':
                    orderByList.append(fieldName)
                else:
                    orderByList.append(f'{fieldName} desc')
            else:
                controlflow.expected_argument_exit(
                    'orderby',
                    ', '.join(sorted(USERINVITATION_ORDERBY_CHOICES_MAP)),
                    fieldName)
        elif myarg == 'todrive':
            todrive = True
            i += 1
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print userinvitations')
    if orderByList:
        orderBy = ' '.join(orderByList)
    else:
        orderBy = None
    gam.printGettingAllItems('User Invitations', filter_)
    page_message = gapi.got_total_items_msg('User Invitations', '...\n')
    invitations = gapi.get_all_pages(svc.customers().userinvitations(),
                                     'list',
                                     'userInvitations',
                                     page_message=page_message,
                                     parent=customer,
                                     filter=filter_,
                                     orderBy=orderBy)
    for invitation in invitations:
        invitation['name'] = _reduce_name(invitation['name'])
        row = {}
        for key, val in invitation.items():
            if key not in titles:
                titles.append(key)
            row[key] = val
        rows.append(row)
    display.write_csv_file(rows, titles, 'User Invitations', todrive)
Example #17
0
def update():

    # Convert [email protected] to [email protected]; eliminate periods in name for [email protected]
    def _cleanConsumerAddress(emailAddress, mapCleanToOriginal):
        atLoc = emailAddress.find('@')
        if atLoc > 0:
            if emailAddress[atLoc + 1:] in ['gmail.com', 'googlemail.com']:
                cleanEmailAddress = emailAddress[:atLoc].replace(
                    '.', '') + '@gmail.com'
                if cleanEmailAddress != emailAddress:
                    mapCleanToOriginal[cleanEmailAddress] = emailAddress
                    return cleanEmailAddress
        return emailAddress

    def _getRoleAndUsers():
        checkSuspended = None
        role = ROLE_MEMBER
        expireTime = None
        i = 5
        if sys.argv[i].lower() in GROUP_ROLES_MAP:
            role = GROUP_ROLES_MAP[sys.argv[i].lower()]
            i += 1
        if sys.argv[i].lower() in ['suspended', 'notsuspended']:
            checkSuspended = sys.argv[i].lower() == 'suspended'
            i += 1
        if sys.argv[i].lower() in ['expire', 'expires']:
            if role != ROLE_MEMBER:
                controlflow.invalid_argument_exit(
                    sys.argv[i], f'role {role}')
            expireTime = utils.get_time_or_delta_from_now(sys.argv[i+1])
            i += 2
        if sys.argv[i].lower() in usergroup_types:
            users_email = gam.getUsersToModify(entity_type=sys.argv[i].lower(),
                                               entity=sys.argv[i + 1],
                                               checkSuspended=checkSuspended,
                                               groupUserMembersOnly=False)
        else:
            users_email = [
                gam.normalizeEmailAddressOrUID(sys.argv[i],
                                               checkForCustomerId=True)
            ]
        return (role, expireTime, users_email)

    ci = gapi_cloudidentity.build('cloudidentity_beta')
    group = sys.argv[3]
    myarg = sys.argv[4].lower()
    items = []
    if myarg in UPDATE_GROUP_SUBCMDS:
        group = gam.normalizeEmailAddressOrUID(group)
        if group.startswith('groups/'):
            parent = group
        else:
            parent = group_email_to_id(ci, group)
        if not parent:
            return
        if myarg == 'add':
            role, expireTime, users_email = _getRoleAndUsers()
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will add {len(users_email)} {role}s.\n')
                for user_email in users_email:
                    item = [
                        'gam', 'update', 'cigroup', f'id:{parent}', 'add', role,
                    ]
                    if expireTime:
                        item.extend(['expires', expireTime])
                    item.append(user_email)
                    items.append(item)
            elif len(users_email) > 0:
                body = {
                    'preferredMemberKey': {
                        'id': users_email[0]
                    },
                    'roles': [{
                        'name': ROLE_MEMBER
                    }]
                }
                if role != ROLE_MEMBER:
                    body['roles'].append({'name': role})
                elif expireTime not in {None, NEVER_TIME}:
                    for role in body['roles']:
                        if role['name'] == ROLE_MEMBER:
                            role['expiryDetail'] = {'expireTime': expireTime}
                add_text = [f'as {role}']
                for i in range(2):
                    try:
                        gapi.call(
                            ci.groups().memberships(),
                            'create',
                            throw_reasons=[
                                gapi_errors.ErrorReason.FOUR_O_NINE,
                                gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                gapi_errors.ErrorReason.RESOURCE_NOT_FOUND,
                                gapi_errors.ErrorReason.INVALID_MEMBER,
                                gapi_errors.ErrorReason.
                                CYCLIC_MEMBERSHIPS_NOT_ALLOWED
                            ],
                            parent=parent,
                            body=body)
                        print(
                            f' Group: {group}, {users_email[0]} Added {" ".join(add_text)}'
                        )
                        break
                    except (gapi_errors.GapiMemberNotFoundError,
                            gapi_errors.GapiResourceNotFoundError,
                            gapi_errors.GapiInvalidMemberError,
                            gapi_errors.GapiCyclicMembershipsNotAllowedError
                           ) as e:
                        print(
                            f' Group: {group}, {users_email[0]} Add {" ".join(add_text)} Failed: {str(e)}'
                        )
                        break
        elif myarg == 'sync':
            syncMembersSet = set()
            syncMembersMap = {}
            role, expireTime, users_email = _getRoleAndUsers()
            for user_email in users_email:
                if user_email in ('*', GC_Values[GC_CUSTOMER_ID]):
                    syncMembersSet.add(GC_Values[GC_CUSTOMER_ID])
                else:
                    syncMembersSet.add(
                        _cleanConsumerAddress(user_email.lower(),
                                              syncMembersMap))
            currentMembersSet = set()
            currentMembersMap = {}
            for current_email in gam.getUsersToModify(
                    entity_type='cigroup',
                    entity=group,
                    member_type=role,
                    groupUserMembersOnly=False):
                if current_email == GC_Values[GC_CUSTOMER_ID]:
                    currentMembersSet.add(current_email)
                else:
                    currentMembersSet.add(
                        _cleanConsumerAddress(current_email.lower(),
                                              currentMembersMap))
            to_add = [
                syncMembersMap.get(emailAddress, emailAddress)
                for emailAddress in syncMembersSet - currentMembersSet
            ]
            to_remove = [
                currentMembersMap.get(emailAddress, emailAddress)
                for emailAddress in currentMembersSet - syncMembersSet
            ]
            sys.stderr.write(
                f'Group: {group}, Will add {len(to_add)} and remove {len(to_remove)} {role}s.\n'
            )
            for user in to_add:
                item = ['gam', 'update', 'cigroup', f'id:{parent}', 'add',
                        role,]
                if role == ROLE_MEMBER and expireTime not in {None, NEVER_TIME}:
                    item.extend(['expires', expireTime])
                item.append(user)
                items.append(item)
            for user in to_remove:
                items.append([
                    'gam', 'update', 'cigroup', f'id:{parent}', 'remove', user
                ])
        elif myarg in ['delete', 'remove']:
            _, _, users_email = _getRoleAndUsers()
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will remove {len(users_email)} emails.\n')
                for user_email in users_email:
                    items.append([
                        'gam', 'update', 'cigroup', f'id:{parent}', 'remove',
                        user_email
                    ])
            elif len(users_email) == 1:
                name = membership_email_to_id(ci, parent, users_email[0])
                try:
                    gapi.call(ci.groups().memberships(),
                              'delete',
                              throw_reasons=[
                                  gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                  gapi_errors.ErrorReason.INVALID_MEMBER
                              ],
                              name=name)
                    print(f' Group: {group}, {users_email[0]} Removed')
                except (gapi_errors.GapiMemberNotFoundError,
                        gapi_errors.GapiInvalidMemberError) as e:
                    print(
                        f' Group: {group}, {users_email[0]} Remove Failed: {str(e)}'
                    )
        elif myarg == 'update':
            role, expireTime, users_email = _getRoleAndUsers()
            if len(users_email) > 1:
                sys.stderr.write(
                    f'Group: {group}, Will update {len(users_email)} {role}s.\n'
                )
                for user_email in users_email:
                    item = [
                        'gam', 'update', 'cigroup', f'id:{parent}', 'update',
                        role,]
                    if expireTime:
                        item.extend(['expires', expireTime])
                    item.append(user_email)
                    items.append(item)
            elif len(users_email) > 0:
                name = membership_email_to_id(ci, parent, users_email[0])
                preUpdateRoles = []
                addRoles = []
                removeRoles = []
                postUpdateRoles = []
                member_roles = gapi.call(ci.groups().memberships(),
                                         'get',
                                         name=name,
                                         fields='roles').get('roles', [{'name': ROLE_MEMBER}])
                current_roles = [crole['name'] for crole in member_roles]
                # When upgrading role, strip any expiryDetail from member before role changes
                if role != ROLE_MEMBER:
                    for crole in member_roles:
                        if 'expiryDetail' in crole:
                            preUpdateRoles.append(
                                {'fieldMask': 'expiryDetail.expireTime',
                                 'membershipRole': {'name': ROLE_MEMBER,
                                                    'expiryDetail': {'expireTime': None}}})
                            break
                # When downgrading role or simply updating member expireTime, update expiryDetail after role changes
                elif expireTime:
                    postUpdateRoles.append(
                        {'fieldMask': 'expiryDetail.expireTime',
                         'membershipRole': {'name': role,
                                            'expiryDetail': {'expireTime':  expireTime if expireTime != NEVER_TIME else None}}})
                for crole in current_roles:
                    if crole not in {ROLE_MEMBER, role}:
                        removeRoles.append(crole)
                if role not in current_roles:
                    new_role = {'name': role}
                    if role == ROLE_MEMBER and expireTime not in {None, NEVER_TIME}:
                        new_role['expiryDetail'] = {'expireTime': expireTime}
                        postUpdateRoles = []
                    addRoles.append(new_role)
                bodys = []
                if preUpdateRoles:
                    bodys.append({'updateRolesParams': preUpdateRoles})
                if addRoles:
                    bodys.append({'addRoles': addRoles})
                if removeRoles:
                    bodys.append({'removeRoles': removeRoles})
                if postUpdateRoles:
                    bodys.append({'updateRolesParams': postUpdateRoles})
                for body in bodys:
                    try:
                        gapi.call(ci.groups().memberships(),
                                  'modifyMembershipRoles',
                                  throw_reasons=[
                                      gapi_errors.ErrorReason.MEMBER_NOT_FOUND,
                                      gapi_errors.ErrorReason.INVALID_MEMBER
                                  ],
                                  name=name,
                                  body=body)
                    except (gapi_errors.GapiMemberNotFoundError,
                            gapi_errors.GapiInvalidMemberError) as e:
                        print(
                            f' Group: {group}, {users_email[0]} Update to {role} Failed: {str(e)}'
                        )
                        break
                print(
                  f' Group: {group}, {users_email[0]} Updated to {role}'
                )

        else:  # clear
            roles = []
            i = 5
            while i < len(sys.argv):
                myarg = sys.argv[i].lower()
                if myarg.upper() in [ROLE_OWNER, ROLE_MANAGER, ROLE_MEMBER]:
                    roles.append(myarg.upper())
                    i += 1
                else:
                    controlflow.invalid_argument_exit(
                        sys.argv[i], 'gam update cigroup clear')
            if not roles:
                roles = [ROLE_MEMBER]
            group = gam.normalizeEmailAddressOrUID(group)
            member_type_message = f'{",".join(roles).lower()}s'
            sys.stderr.write(
                f'Getting {member_type_message} of {group} (may take some time for large groups)...\n'
            )
            page_message = gapi.got_total_items_msg(f'{member_type_message}',
                                                    '...')
            try:
                result = gapi.get_all_pages(
                    ci.groups().memberships(),
                    'list',
                    'memberships',
                    page_message=page_message,
                    throw_reasons=gapi_errors.MEMBERS_THROW_REASONS,
                    parent=parent,
                    fields='nextPageToken,memberships(preferredMemberKey,roles)')
                result = filter_members_to_roles(result, roles)
                if not result:
                    print('Group already has 0 members')
                    return
                users_email = [member['preferredMemberKey']['id'] for member in result]
                sys.stderr.write(
                    f'Group: {group}, Will remove {len(users_email)} {", ".join(roles).lower()}s.\n'
                )
                for user_email in users_email:
                    items.append([
                        'gam', 'update', 'cigroup', group, 'remove', user_email
                    ])
            except (gapi_errors.GapiGroupNotFoundError,
                    gapi_errors.GapiDomainNotFoundError,
                    gapi_errors.GapiInvalidError,
                    gapi_errors.GapiForbiddenError):
                gam.entityUnknownWarning('Group', group, 0, 0)
        if items:
            gam.run_batch(items)
    else:
        i = 4
        body = {}
        sec_body = {}
        while i < len(sys.argv):
            myarg = sys.argv[i].lower().replace('_', '')
            if myarg == 'name':
                body['displayName'] = sys.argv[i + 1]
                i += 2
            elif myarg == 'description':
                body['description'] = sys.argv[i + 1]
                i += 2
            elif myarg == 'security':
                body['labels'] = {
                    'cloudidentity.googleapis.com/groups.security': '',
                    'cloudidentity.googleapis.com/groups.discussion_forum': ''
                }
                i += 1
            elif myarg in ['dynamic']:
                body['dynamicGroupMetadata'] = {
                    'queries': [{
                        'query': sys.argv[i + 1],
                        'resourceType': 'USER'
                    }]
                }
                i += 2
            elif myarg in ['memberrestriction', 'memberrestrictions']:
                query = sys.argv[i + 1]
                member_types = {
                  'USER': '******',
                  'SERVICE_ACCOUNT': '2',
                  'GROUP': '3',
                  }
                for key, val in member_types.items():
                    query = query.replace(key, val)
                sec_body['memberRestriction'] = {'query': query}
                i += 2
            else:
                controlflow.invalid_argument_exit(sys.argv[i],
                                                  'gam update cigroup')
        if body:
            updateMask = ','.join(body.keys())
            name = group_email_to_id(ci, group)
            print(f'Updating group {group}')
            gapi.call(ci.groups(),
                      'patch',
                      updateMask=updateMask,
                      name=name,
                      body=body)
        if sec_body:
            updateMask = 'member_restriction.query'
            # it seems like a bug that API requires /securitySettings
            # appended to name. We'll see if Google servers change this
            # at some point.
            name = f'{group_email_to_id(ci, group)}/securitySettings'
            print(f'Updating group {group} security settings')
            gapi.call(ci.groups(),
                    'updateSecuritySettings',
                    name=name,
                    updateMask=updateMask,
                    body=sec_body)
Example #18
0
def print_members():
    ci = gapi_cloudidentity.build(CIGROUP_API_BETA)
    todrive = False
    gapi_directory_customer.setTrueCustomerId()
    parent = f'customers/{GC_Values[GC_CUSTOMER_ID]}'
    usemember = None
    roles = []
    titles = ['group']
    csvRows = []
    groups_to_get = []
    i = 3
    while i < len(sys.argv):
        myarg = sys.argv[i].lower().replace('_', '')
        if myarg == 'todrive':
            todrive = True
            i += 1
        elif myarg in ['role', 'roles']:
            for role in sys.argv[i + 1].lower().replace(',', ' ').split():
                if role in GROUP_ROLES_MAP:
                    roles.append(GROUP_ROLES_MAP[role])
                else:
                    controlflow.system_error_exit(
                        2,
                        f'{role} is not a valid role for "gam print group-members {myarg}"'
                    )
            i += 2
        elif myarg == 'enterprisemember':
            member = gam.convertUIDtoEmailAddress(
                sys.argv[i + 1], email_types=['user', 'group'])
            usemember = f"member_key_id == '{member}' && 'cloudidentity.googleapis.com/groups.discussion_forum' in labels"
            i += 2
        elif myarg in ['cigroup', 'cigroups']:
            group_email = gam.normalizeEmailAddressOrUID(sys.argv[i + 1])
            groups_to_get = [group_email]
            i += 2
        else:
            controlflow.invalid_argument_exit(sys.argv[i],
                                              'gam print cigroup-members')
    if not groups_to_get:
        groups_to_get = _get_groups_list(ci, usemember, parent)
    i = 0
    count = len(groups_to_get)
    for group_email in groups_to_get:
        i += 1

        sys.stderr.write(
            f'Getting members for {group_email}{gam.currentCountNL(i, count)}')
        group_id = group_email_to_id(ci, group_email)
        print(f'Getting members of cigroup {group_email}...')
        page_message = f' {gapi.got_total_items_first_last_msg("Members")}'
        group_members = gapi.get_all_pages(
            ci.groups().memberships(),
            'list',
            'memberships',
            soft_errors=True,
            parent=group_id,
            view='FULL',
            pageSize=500,
            page_message=page_message,
            message_attribute=[CIGROUP_MEMBERKEY, 'id'])
        #fields=f'nextPageToken,memberships({CIGROUP_MEMBERKEY},roles,createTime,updateTime)')
        if roles:
            group_members = filter_members_to_roles(group_members, roles)
        for member in group_members:
            # reduce role to a single value
            member['role'] = get_single_role(member.pop('roles'))
            member = utils.flatten_json(member)
            for title in member:
                if title not in titles:
                    titles.append(title)
            member['group'] = group_email
            csvRows.append(member)
    display.write_csv_file(csvRows, titles, 'Group Members', todrive)