allow addmember and removemember to accept multiple usernames
continuous-integration/drone/pr Build is passing Details

This commit is contained in:
Max Erenberg 2022-07-01 12:47:52 -04:00
parent dc412ef5cb
commit 40b9f704a3
2 changed files with 86 additions and 67 deletions

View File

@ -68,75 +68,78 @@ def get(group_name):
print_group_lines(result) print_group_lines(result)
@groups.command(short_help='Add a member to a group') @groups.command(short_help='Add one or more members to a group')
@click.argument('group_name') @click.argument('group_name')
@click.argument('username') @click.argument('username')
@click.argument('usernames', nargs=-1)
@click.option('--no-subscribe', is_flag=True, default=False, @click.option('--no-subscribe', is_flag=True, default=False,
help='Do not subscribe the member to any auxiliary mailing lists.') help='Do not subscribe the member(s) to any auxiliary mailing lists.')
def addmember(group_name, username, no_subscribe): def addmember(group_name, username, usernames, no_subscribe):
usernames = [username, *usernames]
if len(usernames) == 1:
click.confirm(f'Are you sure you want to add {username} to {group_name}?', click.confirm(f'Are you sure you want to add {username} to {group_name}?',
abort=True) abort=True)
else:
click.echo(f'The following users will be added to {group_name}:')
click.echo(', '.join(usernames))
click.confirm('Do you want to continue?', abort=True)
base_domain = component.getUtility(IConfig).get('base_domain') base_domain = component.getUtility(IConfig).get('base_domain')
url = f'/api/groups/{group_name}/members/{username}'
operations = AddMemberToGroupTransaction.operations operations = AddMemberToGroupTransaction.operations
if no_subscribe:
operations.remove('subscribe_user_to_auxiliary_mailing_lists')
for username in usernames:
url = f'/api/groups/{group_name}/members/{username}'
if no_subscribe: if no_subscribe:
url += '?subscribe_to_lists=false' url += '?subscribe_to_lists=false'
operations.remove('subscribe_user_to_auxiliary_mailing_lists')
resp = http_post(url) resp = http_post(url)
data = handle_stream_response(resp, operations) data = handle_stream_response(resp, operations)
result = data[-1]['result'] result = data[-1]['result']
lines = [] click.echo(f'Added {username} to ' + ', '.join(result['added_to_groups']))
for i, group in enumerate(result['added_to_groups']): if result.get('subscribed_to_lists'):
if i == 0: mailing_lists = [
prefix = 'Added to groups' mailing_list + '@' + base_domain
else: if '@' not in mailing_list
prefix = '' else mailing_list
lines.append((prefix, group)) for mailing_list in result['subscribed_to_lists']
for i, mailing_list in enumerate(result.get('subscribed_to_lists', [])): ]
if i == 0: click.echo(f'Subscribed {username} to ' + ', '.join(mailing_lists))
prefix = 'Subscribed to lists'
else:
prefix = ''
if '@' not in mailing_list:
mailing_list += '@' + base_domain
lines.append((prefix, mailing_list))
print_colon_kv(lines)
@groups.command(short_help='Remove a member from a group') @groups.command(short_help='Remove one or more members from a group')
@click.argument('group_name') @click.argument('group_name')
@click.argument('username') @click.argument('username')
@click.argument('usernames', nargs=-1)
@click.option('--no-unsubscribe', is_flag=True, default=False, @click.option('--no-unsubscribe', is_flag=True, default=False,
help='Do not unsubscribe the member from any auxiliary mailing lists.') help='Do not unsubscribe the member(s) from any auxiliary mailing lists.')
def removemember(group_name, username, no_unsubscribe): def removemember(group_name, username, usernames, no_unsubscribe):
usernames = [username, *usernames]
if len(usernames) == 1:
click.confirm(f'Are you sure you want to remove {username} from {group_name}?', click.confirm(f'Are you sure you want to remove {username} from {group_name}?',
abort=True) abort=True)
else:
click.echo(f'The following users will be removed from {group_name}:')
click.echo(', '.join(usernames))
click.confirm('Do you want to continue?', abort=True)
base_domain = component.getUtility(IConfig).get('base_domain') base_domain = component.getUtility(IConfig).get('base_domain')
url = f'/api/groups/{group_name}/members/{username}'
operations = RemoveMemberFromGroupTransaction.operations operations = RemoveMemberFromGroupTransaction.operations
if no_unsubscribe: if no_unsubscribe:
url += '?unsubscribe_from_lists=false'
operations.remove('unsubscribe_user_from_auxiliary_mailing_lists') operations.remove('unsubscribe_user_from_auxiliary_mailing_lists')
for username in usernames:
url = f'/api/groups/{group_name}/members/{username}'
if no_unsubscribe:
url += '?unsubscribe_from_lists=false'
resp = http_delete(url) resp = http_delete(url)
data = handle_stream_response(resp, operations) data = handle_stream_response(resp, operations)
result = data[-1]['result'] result = data[-1]['result']
lines = [] click.echo(f'Removed {username} from ' + ', '.join(result['removed_from_groups']))
for i, group in enumerate(result['removed_from_groups']): if result.get('unsubscribed_from_lists'):
if i == 0: mailing_lists = [
prefix = 'Removed from groups' mailing_list + '@' + base_domain
else: if '@' not in mailing_list
prefix = '' else mailing_list
lines.append((prefix, group)) for mailing_list in result['unsubscribed_from_lists']
for i, mailing_list in enumerate(result.get('unsubscribed_from_lists', [])): ]
if i == 0: click.echo(f'Unsubscribed {username} from ' + ', '.join(mailing_lists))
prefix = 'Unsubscribed from lists'
else:
prefix = ''
if '@' not in mailing_list:
mailing_list += '@' + base_domain
lines.append((prefix, mailing_list))
print_colon_kv(lines)
@groups.command(short_help='Delete a group') @groups.command(short_help='Delete a group')

View File

@ -47,7 +47,7 @@ def test_groups(cli_setup, ldap_user):
"Add user to auxiliary groups... Skipped\n" "Add user to auxiliary groups... Skipped\n"
"Subscribe user to auxiliary mailing lists... Skipped\n" "Subscribe user to auxiliary mailing lists... Skipped\n"
"Transaction successfully completed.\n" "Transaction successfully completed.\n"
"Added to groups: test_group_1\n" f"Added {ldap_user.uid} to test_group_1\n"
) )
assert result.exit_code == 0 assert result.exit_code == 0
assert result.output == expected assert result.output == expected
@ -68,7 +68,7 @@ def test_groups(cli_setup, ldap_user):
"Remove user from auxiliary groups... Skipped\n" "Remove user from auxiliary groups... Skipped\n"
"Unsubscribe user from auxiliary mailing lists... Skipped\n" "Unsubscribe user from auxiliary mailing lists... Skipped\n"
"Transaction successfully completed.\n" "Transaction successfully completed.\n"
"Removed from groups: test_group_1\n" f"Removed {ldap_user.uid} from test_group_1\n"
) )
assert result.exit_code == 0 assert result.exit_code == 0
assert result.output == expected assert result.output == expected
@ -92,6 +92,28 @@ def delete_group(group_name):
assert result.exit_code == 0 assert result.exit_code == 0
def test_groups_multiple_members(cli_setup, new_user_gen):
runner = CliRunner()
create_group('test_group_1', 'Test Group 1')
with new_user_gen() as user1, new_user_gen() as user2:
result = runner.invoke(cli, [
'groups', 'addmember', 'test_group_1', user1.uid, user2.uid
], input='y\n')
assert result.exit_code == 0
lines = result.output.splitlines()
assert f'Added {user1.uid} to test_group_1' in lines
assert f'Added {user2.uid} to test_group_1' in lines
result = runner.invoke(cli, [
'groups', 'removemember', 'test_group_1', user1.uid, user2.uid
], input='y\n')
assert result.exit_code == 0
lines = result.output.splitlines()
assert f'Removed {user1.uid} from test_group_1' in lines
assert f'Removed {user2.uid} from test_group_1' in lines
delete_group('test_group_1')
def test_groups_with_auxiliary_groups_and_mailing_lists(cli_setup, ldap_user): def test_groups_with_auxiliary_groups_and_mailing_lists(cli_setup, ldap_user):
runner = CliRunner() runner = CliRunner()
# make sure auxiliary groups + mailing lists exist in ceod_test_local.ini # make sure auxiliary groups + mailing lists exist in ceod_test_local.ini
@ -109,11 +131,8 @@ def test_groups_with_auxiliary_groups_and_mailing_lists(cli_setup, ldap_user):
"Add user to auxiliary groups... Done\n" "Add user to auxiliary groups... Done\n"
"Subscribe user to auxiliary mailing lists... Done\n" "Subscribe user to auxiliary mailing lists... Done\n"
"Transaction successfully completed.\n" "Transaction successfully completed.\n"
"Added to groups: syscom\n" f"Added {ldap_user.uid} to syscom, office, staff\n"
" office\n" f"Subscribed {ldap_user.uid} to syscom@csclub.internal, syscom-alerts@csclub.internal\n"
" staff\n"
"Subscribed to lists: syscom@csclub.internal\n"
" syscom-alerts@csclub.internal\n"
) )
assert result.exit_code == 0 assert result.exit_code == 0
assert result.output == expected assert result.output == expected
@ -128,11 +147,8 @@ def test_groups_with_auxiliary_groups_and_mailing_lists(cli_setup, ldap_user):
"Remove user from auxiliary groups... Done\n" "Remove user from auxiliary groups... Done\n"
"Unsubscribe user from auxiliary mailing lists... Done\n" "Unsubscribe user from auxiliary mailing lists... Done\n"
"Transaction successfully completed.\n" "Transaction successfully completed.\n"
"Removed from groups: syscom\n" f"Removed {ldap_user.uid} from syscom, office, staff\n"
" office\n" f"Unsubscribed {ldap_user.uid} from syscom@csclub.internal, syscom-alerts@csclub.internal\n"
" staff\n"
"Unsubscribed from lists: syscom@csclub.internal\n"
" syscom-alerts@csclub.internal\n"
) )
assert result.exit_code == 0 assert result.exit_code == 0
assert result.output == expected assert result.output == expected
@ -142,14 +158,14 @@ def test_groups_with_auxiliary_groups_and_mailing_lists(cli_setup, ldap_user):
'groups', 'addmember', 'syscom', ldap_user.uid, '--no-subscribe', 'groups', 'addmember', 'syscom', ldap_user.uid, '--no-subscribe',
], input='y\n') ], input='y\n')
assert result.exit_code == 0 assert result.exit_code == 0
assert 'Subscribed to lists' not in result.output assert 'Subscribed' not in result.output
runner = CliRunner() runner = CliRunner()
result = runner.invoke(cli, [ result = runner.invoke(cli, [
'groups', 'removemember', 'syscom', ldap_user.uid, '--no-unsubscribe', 'groups', 'removemember', 'syscom', ldap_user.uid, '--no-unsubscribe',
], input='y\n') ], input='y\n')
assert result.exit_code == 0 assert result.exit_code == 0
assert 'Unsubscribed from lists' not in result.output assert 'Unsubscribed' not in result.output
delete_group('syscom') delete_group('syscom')
delete_group('office') delete_group('office')