def validate_username(username, realname): """Validates a username and realname pair to ensure: * Username isn't already in use * Username is based on realname * Username isn't restricted.""" if search.user_exists(username): raise ValidationError('Username {} already exists.'.format(username)) try: validators.validate_username(username) except ValueError as ex: raise ValidationError(str(ex)) SIMILARITY_THRESHOLD = 2 if similarity_heuristic(realname, username) > SIMILARITY_THRESHOLD: raise ValidationWarning( 'Username {} not based on real name {}'.format(username, realname)) if any(word in username for word in constants.BAD_WORDS): raise ValidationWarning('Username {} contains bad words'.format(username)) if any(word in username for word in constants.RESTRICTED_WORDS): raise ValidationWarning('Username {} contains restricted words'.format(username))
def change_password_with_keytab(username, password, keytab, principal, comment=None): """Change a user's Kerberos password using a keytab, subject to username and password validation. :param comment: comment to include in notification email """ validators.validate_username(username, check_exists=True) validators.validate_password(username, password) # try changing using kadmin pexpect cmd = '{kadmin_path} -K {keytab} -p {principal} cpw {username}'.format( kadmin_path=shlex.quote(KADMIN_PATH), keytab=shlex.quote(keytab), principal=shlex.quote(principal), username=shlex.quote(username)) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:"******"Verify password - {}@OCF.BERKELEY.EDU's Password:".format(username)) child.sendline(password) child.expect(pexpect.EOF) output = child.before.decode('utf8') if 'kadmin' in output: raise ValueError('kadmin Error: {}'.format(output)) _notify_password_change(username, comment=comment)
def validate_username(username, realname): """Validates a username and realname pair to ensure: * Username isn't already in use * Username is based on realname * Username isn't restricted.""" if search.user_exists(username): raise ValidationError('Username {} already exists.'.format(username)) try: validators.validate_username(username) except ValueError as ex: raise ValidationError(str(ex)) SIMILARITY_THRESHOLD = 2 if similarity_heuristic(realname, username) > SIMILARITY_THRESHOLD: raise ValidationWarning('Username {} not based on real name {}'.format( username, realname)) if any(word in username for word in constants.BAD_WORDS): raise ValidationWarning( 'Username {} contains bad words'.format(username)) if any(word in username for word in constants.RESTRICTED_WORDS): raise ValidationWarning( 'Username {} contains restricted words'.format(username))
def change_password_with_keytab(username, password, keytab, principal, comment=None): """Change a user's Kerberos password using a keytab, subject to username and password validation. :param comment: comment to include in notification email """ validators.validate_username(username, check_exists=True) validators.validate_password(username, password) # try changing using kadmin pexpect cmd = '{kadmin_path} -K {keytab} -p {principal} cpw {username}'.format( kadmin_path=shell.escape_arg(constants.KADMIN_PATH), keytab=shell.escape_arg(keytab), principal=shell.escape_arg(principal), username=shell.escape_arg(username)) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:"******"Verify password - {}@OCF.BERKELEY.EDU's Password:" .format(username)) child.sendline(password) child.expect(pexpect.EOF) output = child.before.decode('utf8') if 'kadmin' in output: raise ValueError('kadmin Error: {}'.format(output)) _notify_password_change(username, comment=comment)
def change_password_with_staffer(username, password, principal, admin_password): """Change a user's Kerberos password using kadmin and a password, subject to username and password validation.""" validators.validate_username(username) validators.validate_password(username, password) # try changing using kadmin pexpect cmd = '{kadmin_path} -p {principal} cpw {username}'.format( kadmin_path=shell.escape_arg(constants.KADMIN_PATH), principal=shell.escape_arg(principal), username=shell.escape_arg(username)) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:"******"Verify password - {}@OCF.BERKELEY.EDU's Password:"******"{}@OCF.BERKELEY.EDU's Password:".format(principal)) child.sendline(admin_password) child.expect(pexpect.EOF) output = child.before.decode('utf8') if 'Looping detected' in output: raise ValueError('Invalid admin password given.') elif 'kadmin' in output: raise ValueError('kadmin Error: {}'.format(output)) _notify_password_change(username)
def test_failure_nonexist(self): """Test that it fails with a nonexistent username. We can't just use "nonexist" since this is also a reserved username. We need mocking to avoid flakiness if somebody registers that account. """ with mock.patch('ocflib.account.validators.user_exists', return_value=False) as m, \ pytest.raises(ValueError): validate_username('asdf', check_exists=True) m.assert_called_once_with('asdf')
def test_failure_nonexist(self): """Test that it fails with a nonexistent username. We can't just use "nonexist" since this is also a reserved username. We need mocking to avoid flakiness if somebody registers that account. """ with mock.patch('ocflib.account.validators.user_exists', return_value=False) as m, \ pytest.raises(ValueError): validate_username('asdf', check_exists=True) m.assert_called_once_with('asdf')
def password_matches(username, password): """Returns True if the password matches the user account given""" validators.validate_username(username) validators.validate_password(username, password, strength_check=False) if not validators.user_exists(username): raise ValueError("User doesn't exist") cmd = 'kinit --no-forwardable -l0 {}@OCF.BERKELEY.EDU'.format(username) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:".format(username)) child.sendline(password) child.expect(pexpect.EOF) child.close() return child.exitstatus == 0
def password_matches(username, password): """Returns True if the password matches the user account given""" validators.validate_username(username) validators.validate_password(username, password, strength_check=False) if not validators.user_exists(username): raise ValueError("User doesn't exist") cmd = 'kinit --no-forwardable -l0 {}@OCF.BERKELEY.EDU'.format(username) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:".format(username)) child.sendline(password) child.expect(pexpect.EOF) child.close() return child.exitstatus == 0
def change_password_with_staffer(username, password, principal, admin_password, comment=None): """Change a user's Kerberos password using kadmin and a password, subject to username and password validation. :param comment: comment to include in notification email """ validators.validate_username(username) validators.validate_password(username, password) # try changing using kadmin pexpect cmd = '{kadmin_path} -p {principal} cpw {username}'.format( kadmin_path=shlex.quote(KADMIN_PATH), principal=shlex.quote(principal), username=shlex.quote(username)) child = pexpect.spawn(cmd, timeout=10) child.expect("{}@OCF.BERKELEY.EDU's Password:"******"Verify password - {}@OCF.BERKELEY.EDU's Password:"******"{}@OCF.BERKELEY.EDU's Password:".format(principal)) child.sendline(admin_password) child.expect(pexpect.EOF) output = child.before.decode('utf8') if 'Looping detected' in output: raise ValueError('Invalid admin password given.') elif 'kadmin' in output: raise ValueError('kadmin Error: {}'.format(output)) _notify_password_change(username, comment=comment)
def test_success(fail, username): validate_username(username, check_exists=True)
def test_failure(self, username): with pytest.raises(ValueError): validate_username(username, check_exists=True)
def test_success(fail, username): validate_username(username, check_exists=True)
def test_failure(self, username): with pytest.raises(ValueError): validate_username(username, check_exists=True)