package org.apereo.cas.trusted.authentication.storage;
import org.apache.commons.lang3.StringUtils;
import org.apereo.cas.CipherExecutor;
import org.apereo.cas.trusted.util.MultifactorAuthenticationTrustUtils;
import org.apereo.cas.trusted.authentication.api.MultifactorAuthenticationTrustRecord;
import org.apereo.cas.trusted.authentication.api.MultifactorAuthenticationTrustStorage;
import org.apereo.inspektr.audit.annotation.Audit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.Set;
/**
* This is {@link BaseMultifactorAuthenticationTrustStorage}.
*
* @author Misagh Moayyed
* @since 5.0.0
*/
@EnableTransactionManagement(proxyTargetClass = true)
@Transactional(transactionManager = "transactionManagerMfaAuthnTrust")
public abstract class BaseMultifactorAuthenticationTrustStorage implements MultifactorAuthenticationTrustStorage {
private static final Logger LOGGER = LoggerFactory.getLogger(BaseMultifactorAuthenticationTrustStorage.class);
private CipherExecutor<Serializable, String> cipherExecutor;
@Audit(action = "TRUSTED_AUTHENTICATION", actionResolverName = "TRUSTED_AUTHENTICATION_ACTION_RESOLVER",
resourceResolverName = "TRUSTED_AUTHENTICATION_RESOURCE_RESOLVER")
@Override
public MultifactorAuthenticationTrustRecord set(final MultifactorAuthenticationTrustRecord record) {
LOGGER.debug("Stored authentication trust record for [{}]", record);
record.setKey(generateKey(record));
return setInternal(record);
}
@Override
public Set<MultifactorAuthenticationTrustRecord> get(final String principal, final LocalDate onOrAfterDate) {
final Set<MultifactorAuthenticationTrustRecord> res = get(principal);
res.removeIf(entry -> {
if (entry.getDate().isBefore(onOrAfterDate)) {
return true;
}
final String decodedKey = this.cipherExecutor.decode(entry.getKey());
final String currentKey = MultifactorAuthenticationTrustUtils.generateKey(entry);
if (StringUtils.isBlank(decodedKey)) {
return true;
}
return !decodedKey.equals(currentKey);
});
return res;
}
/**
* Generate key .
*
* @param r the record
* @return the string
*/
protected String generateKey(final MultifactorAuthenticationTrustRecord r) {
return cipherExecutor.encode(MultifactorAuthenticationTrustUtils.generateKey(r));
}
public void setCipherExecutor(final CipherExecutor<Serializable, String> cipherExecutor) {
this.cipherExecutor = cipherExecutor;
}
@Override
public String toString() {
return getClass().getSimpleName();
}
/**
* Set records.
*
* @param record the record
* @return the record
*/
protected abstract MultifactorAuthenticationTrustRecord setInternal(MultifactorAuthenticationTrustRecord record);
}