def test_configure_live_does_not_leak_passwords(tmpdir, capsys, cursor, db_config): """ We add a new user (NEW_USER) through pgbedrock and make sure that 1) this change isn't committed if we pass --check and 2) this change _is_ committed if we pass --live """ # Assert that we start without the role we are trying to add cursor.execute(Q_GET_ROLE_ATTRIBUTE.format('rolname', NEW_USER)) assert cursor.rowcount == 0 new_password = '******' spec_path = tmpdir.join('spec.yml') spec_path.write(""" postgres: is_superuser: yes owns: schemas: - information_schema - pg_catalog - public test_user: can_login: yes is_superuser: yes attributes: - PASSWORD "test_password" {new_user}: attributes: - PASSWORD "{new_password}" """.format(new_user=NEW_USER, new_password=new_password)) params = copy.deepcopy(db_config) params.update( dict( spec=spec_path.strpath, prompt=False, attributes=True, memberships=True, ownerships=True, privileges=True, live=True, verbose=True, )) core_configure.configure(**params) # Verify that the password was changed new_md5_hash = attr.create_md5_hash(NEW_USER, new_password) cursor.execute( "SELECT rolpassword FROM pg_authid WHERE rolname = '{}';".format( NEW_USER)) assert cursor.fetchone()[0] == new_md5_hash # Verify that the password isn't exposed in our output out, err = capsys.readouterr() assert 'supersecret' not in out assert 'supersecret' not in err # Verify that the sanitized record of the password change is in our output assert 'ALTER ROLE "foobar" WITH ENCRYPTED PASSWORD \'******\';' in out
def test_set_all_attributes_change_skips_same_password(mockdbcontext, password): role_attributes = copy.deepcopy(attr.DEFAULT_ATTRIBUTES) role_attributes.update( dict(rolpassword=attr.create_md5_hash(ROLE1, 'supersecret'))) mockdbcontext.get_role_attributes = lambda x: role_attributes attributes = ['PASSWORD {}'.format(password)] roleconf = attr.AttributeAnalyzer(ROLE1, spec_attributes=attributes, dbcontext=mockdbcontext) attributes = roleconf.coalesce_attributes() roleconf.set_all_attributes(attributes) assert roleconf.sql_to_run == []
opt = 'rolvaliduntil' val = '2019-09-09' curr_val = 'infinity' assert roleconf.get_attribute_value(opt) != val roleconf.set_attribute_value(attribute=opt, desired_value=val, current_value=curr_val) expected = [attr.Q_ALTER_VALID_UNTIL.format(ROLE1, val, curr_val)] assert roleconf.sql_to_run == expected @nondefault_attributes( dict(rolpassword=attr.create_md5_hash(ROLE1, 'supersecret'), )) @pytest.mark.parametrize('desired_value, expected', [('supersecret', True), ('incorrect_password', False)]) def test_is_same_password(roleconf, desired_value, expected): assert roleconf.is_same_password(desired_value) == expected def test_is_same_password_if_empty(roleconf): assert roleconf.is_same_password(None) is True @nondefault_attributes( dict(rolpassword=attr.create_md5_hash(ROLE1, 'supersecret'), )) def test_set_password_statements_generated(roleconf): desired_value = 'evenmoresecret'