package org.apereo.cas.adaptors.gauth.repository.credentials;
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
import com.warrenstrange.googleauth.IGoogleAuthenticator;
import org.apereo.cas.configuration.model.support.mfa.MultifactorAuthenticationProperties;
import org.apereo.cas.otp.repository.credentials.BaseOneTimeTokenCredentialRepository;
import org.apereo.cas.otp.repository.credentials.OneTimeTokenAccount;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* This is {@link RestGoogleAuthenticatorTokenCredentialRepository}.
*
* @author Misagh Moayyed
* @since 5.1.0
*/
public class RestGoogleAuthenticatorTokenCredentialRepository extends BaseOneTimeTokenCredentialRepository {
private static final Logger LOGGER = LoggerFactory.getLogger(RestGoogleAuthenticatorTokenCredentialRepository.class);
private final IGoogleAuthenticator googleAuthenticator;
private final RestTemplate restTemplate;
private final MultifactorAuthenticationProperties.GAuth gauth;
public RestGoogleAuthenticatorTokenCredentialRepository(final IGoogleAuthenticator googleAuthenticator,
final RestTemplate restTemplate,
final MultifactorAuthenticationProperties.GAuth gauth) {
this.googleAuthenticator = googleAuthenticator;
this.restTemplate = restTemplate;
this.gauth = gauth;
}
@Override
public String getSecret(final String username) {
final MultifactorAuthenticationProperties.GAuth.Rest rest = gauth.getRest();
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.put("username", Arrays.asList(username));
final HttpEntity<String> entity = new HttpEntity<>(headers);
final ResponseEntity<String> result = restTemplate.exchange(rest.getEndpointUrl(), HttpMethod.GET, entity, String.class);
if (result.getStatusCodeValue() == HttpStatus.OK.value()) {
return result.getBody();
}
return null;
}
@Override
public void save(final String userName, final String secretKey, final int validationCode, final List<Integer> scratchCodes) {
final MultifactorAuthenticationProperties.GAuth.Rest rest = gauth.getRest();
final HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.put("username", Arrays.asList(userName));
headers.put("validationCode", Arrays.asList(String.valueOf(validationCode)));
headers.put("secretKey", Arrays.asList(secretKey));
headers.put("scratchCodes", scratchCodes.stream().map(String::valueOf).collect(Collectors.toList()));
final HttpEntity<String> entity = new HttpEntity<>(headers);
final ResponseEntity<Boolean> result = restTemplate.exchange(rest.getEndpointUrl(), HttpMethod.POST, entity, Boolean.class);
if (result.getStatusCodeValue() == HttpStatus.OK.value()) {
LOGGER.debug("Posted google authenticator account successfully");
}
LOGGER.warn("Failed to save google authenticator account successfully");
}
@Override
public OneTimeTokenAccount create(final String username) {
final GoogleAuthenticatorKey key = this.googleAuthenticator.createCredentials();
return new GoogleAuthenticatorAccount(username, key.getKey(), key.getVerificationCode(), key.getScratchCodes());
}
}