|
|
|
import os
|
|
|
|
import re
|
|
|
|
import shutil
|
|
|
|
from datetime import datetime, timedelta
|
|
|
|
|
|
|
|
from click.testing import CliRunner
|
|
|
|
|
|
|
|
from ceo.cli import cli
|
|
|
|
from ceo_common.model import Term
|
|
|
|
from tests.utils import set_datetime_in_app_process, restore_datetime_in_app_process
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_get(cli_setup, ldap_user):
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(cli, ['members', 'get', ldap_user.uid])
|
|
|
|
expected = (
|
|
|
|
f"uid: {ldap_user.uid}\n"
|
|
|
|
f"full name: {ldap_user.cn}\n"
|
|
|
|
f"first name: {ldap_user.given_name}\n"
|
|
|
|
f"last name: {ldap_user.sn}\n"
|
|
|
|
f"program: {ldap_user.program}\n"
|
|
|
|
f"UID number: {ldap_user.uid_number}\n"
|
|
|
|
f"GID number: {ldap_user.gid_number}\n"
|
|
|
|
f"login shell: {ldap_user.login_shell}\n"
|
|
|
|
f"home directory: {ldap_user.home_directory}\n"
|
|
|
|
f"is a club: {ldap_user.is_club()}\n"
|
|
|
|
f"is a club rep: {ldap_user.is_club_rep}\n"
|
|
|
|
"forwarding addresses: \n"
|
|
|
|
f"member terms: {','.join(ldap_user.terms)}\n"
|
|
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_add(cli_setup):
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(cli, [
|
|
|
|
'members', 'add', 'test_1', '--cn', 'Test One', '--given-name', 'Test',
|
|
|
|
'--sn', 'One', '--program', 'Math', '--terms', '1',
|
|
|
|
], input='y\n')
|
|
|
|
expected_pat = re.compile((
|
|
|
|
"^The following user will be created:\n"
|
|
|
|
"uid: test_1\n"
|
|
|
|
"full name: Test One\n"
|
|
|
|
"first name: Test\n"
|
|
|
|
"last name: One\n"
|
|
|
|
"program: Math\n"
|
|
|
|
"forwarding addresses: test_1@uwaterloo.internal\n"
|
|
|
|
"member terms: [sfw]\\d{4}\n"
|
|
|
|
"Do you want to continue\\? \\[y/N\\]: y\n"
|
|
|
|
"Add user to LDAP... Done\n"
|
|
|
|
"Add group to LDAP... Done\n"
|
|
|
|
"Add user to Kerberos... Done\n"
|
|
|
|
"Create home directory... Done\n"
|
|
|
|
"Set forwarding addresses... Done\n"
|
|
|
|
"Send welcome message... Done\n"
|
|
|
|
"Subscribe to mailing list... Done\n"
|
|
|
|
"Announce new user to mailing list... Done\n"
|
|
|
|
"Transaction successfully completed.\n"
|
|
|
|
"uid: test_1\n"
|
|
|
|
"full name: Test One\n"
|
|
|
|
"first name: Test\n"
|
|
|
|
"last name: One\n"
|
|
|
|
"program: Math\n"
|
|
|
|
"UID number: \\d{5}\n"
|
|
|
|
"GID number: \\d{5}\n"
|
|
|
|
"login shell: /bin/bash\n"
|
|
|
|
"home directory: [a-z0-9/_-]+/test_1\n"
|
|
|
|
"is a club: False\n"
|
|
|
|
"is a club rep: False\n"
|
|
|
|
"forwarding addresses: test_1@uwaterloo\\.internal\n"
|
|
|
|
"member terms: [sfw]\\d{4}\n"
|
|
|
|
"password: \\S+\n$"
|
|
|
|
), re.MULTILINE)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert expected_pat.match(result.output) is not None
|
|
|
|
|
|
|
|
result = runner.invoke(cli, ['members', 'delete', 'test_1'], input='y\n')
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_modify(cli_setup, ldap_user):
|
|
|
|
# The homedir needs to exist so the API can write to ~/.forward
|
|
|
|
os.makedirs(ldap_user.home_directory)
|
|
|
|
try:
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(cli, [
|
|
|
|
'members', 'modify', ldap_user.uid, '--login-shell', '/bin/sh',
|
|
|
|
'--forwarding-addresses', 'jdoe@test1.internal,jdoe@test2.internal',
|
|
|
|
], input='y\n')
|
|
|
|
expected = (
|
|
|
|
"Login shell will be set to: /bin/sh\n"
|
|
|
|
"~/.forward will be set to: jdoe@test1.internal\n"
|
|
|
|
" jdoe@test2.internal\n"
|
|
|
|
"Do you want to continue? [y/N]: y\n"
|
|
|
|
"Replace login shell... Done\n"
|
|
|
|
"Replace forwarding addresses... Done\n"
|
|
|
|
"Transaction successfully completed.\n"
|
|
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == expected
|
|
|
|
finally:
|
|
|
|
shutil.rmtree(ldap_user.home_directory)
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_renew(cli_setup, ldap_user, g_admin_ctx):
|
|
|
|
# set the user's last term to something really old
|
|
|
|
with g_admin_ctx(), ldap_user.ldap_srv.entry_ctx_for_user(ldap_user) as entry:
|
|
|
|
entry.term = ['s1999', 'f1999']
|
|
|
|
current_term = Term.current()
|
|
|
|
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(cli, [
|
|
|
|
'members', 'renew', ldap_user.uid, '--terms', '1',
|
|
|
|
], input='y\n')
|
|
|
|
expected = (
|
|
|
|
f"The following member terms will be added: {current_term}\n"
|
|
|
|
"Do you want to continue? [y/N]: y\n"
|
|
|
|
"Done.\n"
|
|
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == expected
|
|
|
|
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(cli, [
|
|
|
|
'members', 'renew', ldap_user.uid, '--terms', '2',
|
|
|
|
], input='y\n')
|
|
|
|
expected = (
|
|
|
|
f"The following member terms will be added: {current_term+1},{current_term+2}\n"
|
|
|
|
"Do you want to continue? [y/N]: y\n"
|
|
|
|
"Done.\n"
|
|
|
|
)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == expected
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_pwreset(cli_setup, ldap_user, krb_user):
|
|
|
|
runner = CliRunner()
|
|
|
|
result = runner.invoke(
|
|
|
|
cli, ['members', 'pwreset', ldap_user.uid], input='y\n')
|
|
|
|
expected_pat = re.compile((
|
|
|
|
f"^Are you sure you want to reset {ldap_user.uid}'s password\\? \\[y/N\\]: y\n"
|
|
|
|
"New password: \\S+\n$"
|
|
|
|
), re.MULTILINE)
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert expected_pat.match(result.output) is not None
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_expire(cli_setup, app_process, ldap_user, syscom_group):
|
|
|
|
runner = CliRunner()
|
|
|
|
|
|
|
|
try:
|
|
|
|
# use a time that we know for sure will expire
|
|
|
|
test_date = datetime(4000, 4, 1)
|
|
|
|
set_datetime_in_app_process(app_process, test_date)
|
|
|
|
|
|
|
|
result = runner.invoke(cli, ['members', 'expire', '--dry-run'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == f"The following members will be marked as expired:\n{ldap_user.uid}\n"
|
|
|
|
|
|
|
|
result = runner.invoke(cli, ['members', 'expire'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == f"The following members has been marked as expired:\n{ldap_user.uid}\n"
|
|
|
|
|
|
|
|
runner.invoke(cli, ['members', 'renew', ldap_user.uid, '--terms', '1'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
|
|
|
|
result = runner.invoke(cli, ['members', 'expire', '--dry-run'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == ''
|
|
|
|
finally:
|
|
|
|
restore_datetime_in_app_process(app_process)
|
|
|
|
|
|
|
|
|
|
|
|
def test_members_remindexpire(cli_setup, app_process, ldap_user):
|
|
|
|
runner = CliRunner()
|
|
|
|
term = Term(ldap_user.terms[0])
|
|
|
|
|
|
|
|
try:
|
|
|
|
test_date = (term + 1).to_datetime()
|
|
|
|
set_datetime_in_app_process(app_process, test_date)
|
|
|
|
result = runner.invoke(cli, ['members', 'remindexpire', '--dry-run'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == (
|
|
|
|
"The following members will be sent membership renewal reminders:\n"
|
|
|
|
f"{ldap_user.uid}\n"
|
|
|
|
)
|
|
|
|
|
|
|
|
result = runner.invoke(cli, ['members', 'remindexpire'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == (
|
|
|
|
"The following members were sent membership renewal reminders:\n"
|
|
|
|
f"{ldap_user.uid}\n"
|
|
|
|
)
|
|
|
|
|
|
|
|
test_date = (term + 1).to_datetime() + timedelta(days=40)
|
|
|
|
set_datetime_in_app_process(app_process, test_date)
|
|
|
|
result = runner.invoke(cli, ['members', 'remindexpire'])
|
|
|
|
assert result.exit_code == 0
|
|
|
|
assert result.output == "No members are pending expiration.\n"
|
|
|
|
finally:
|
|
|
|
restore_datetime_in_app_process(app_process)
|