package org.apereo.cas.pm.jdbc; import org.apache.commons.lang3.StringUtils; import org.apache.commons.validator.routines.EmailValidator; import org.apereo.cas.CipherExecutor; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.UsernamePasswordCredential; import org.apereo.cas.configuration.model.support.pm.PasswordManagementProperties; import org.apereo.cas.configuration.support.Beans; import org.apereo.cas.pm.BasePasswordManagementService; import org.apereo.cas.pm.PasswordChangeBean; import org.apereo.inspektr.audit.annotation.Audit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.util.Assert; import javax.sql.DataSource; import java.io.Serializable; import java.util.Map; /** * This is {@link JdbcPasswordManagementService}. * * @author Misagh Moayyed * @since 5.1.0 */ public class JdbcPasswordManagementService extends BasePasswordManagementService { private static final Logger LOGGER = LoggerFactory.getLogger(JdbcPasswordManagementService.class); private final JdbcTemplate jdbcTemplate; public JdbcPasswordManagementService(final CipherExecutor<Serializable, String> cipherExecutor, final String issuer, final PasswordManagementProperties passwordManagementProperties, final DataSource dataSource) { super(cipherExecutor, issuer, passwordManagementProperties); this.jdbcTemplate = new JdbcTemplate(dataSource); } @Audit(action = "CHANGE_PASSWORD", actionResolverName = "CHANGE_PASSWORD_ACTION_RESOLVER", resourceResolverName = "CHANGE_PASSWORD_RESOURCE_RESOLVER") @Override public boolean change(final Credential credential, final PasswordChangeBean bean) { Assert.notNull(credential, "Credential cannot be null"); Assert.notNull(bean, "PasswordChangeBean cannot be null"); final UsernamePasswordCredential c = (UsernamePasswordCredential) credential; final PasswordEncoder encoder = Beans.newPasswordEncoder(passwordManagementProperties.getJdbc().getPasswordEncoder()); final String password = encoder.encode(bean.getPassword()); final int count = this.jdbcTemplate.update(passwordManagementProperties.getJdbc().getSqlChangePassword(), password, c.getId()); return count > 0; } @Override public String findEmail(final String username) { final String email = this.jdbcTemplate.queryForObject(passwordManagementProperties.getJdbc().getSqlFindEmail(), String.class, username); if (StringUtils.isNotBlank(email) && EmailValidator.getInstance().isValid(email)) { return email; } return null; } @Override public Map<String, String> getSecurityQuestions(final String username) { final Map map = jdbcTemplate.queryForMap(passwordManagementProperties.getJdbc().getSqlSecurityQuestions(), username); LOGGER.debug("Found [{}] security questions for [{}]", map.size(), username); return map; } }