Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.keycloak.models.credential.OTPCredentialModel Maven / Gradle / Ivy
package org.keycloak.models.credential;
import org.keycloak.common.util.Time;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.credential.dto.OTPCredentialData;
import org.keycloak.models.credential.dto.OTPSecretData;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.RealmModel;
import org.keycloak.models.utils.Base32;
import org.keycloak.util.JsonSerialization;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class OTPCredentialModel extends CredentialModel {
public static final String TYPE = "otp";
public static final String TOTP = "totp";
public static final String HOTP = "hotp";
/**
* The supported encodings when reading the raw secret from the storage
*/
public enum SecretEncoding {
BASE32
}
private final OTPCredentialData credentialData;
private final OTPSecretData secretData;
private OTPCredentialModel(String secretValue, String subType, int digits, int counter, int period, String algorithm) {
this(secretValue, subType, digits, counter, period, algorithm, null);
}
private OTPCredentialModel(String secretValue, String subType, int digits, int counter, int period, String algorithm, String secretEncoding) {
credentialData = new OTPCredentialData(subType, digits, counter, period, algorithm, secretEncoding);
secretData = new OTPSecretData(secretValue);
}
private OTPCredentialModel(OTPCredentialData credentialData, OTPSecretData secretData) {
this.credentialData = credentialData;
this.secretData = secretData;
}
public static OTPCredentialModel createTOTP(String secretValue, int digits, int period, String algorithm){
return createTOTP(secretValue, digits, period, algorithm, null);
}
public static OTPCredentialModel createTOTP(String secretValue, int digits, int period, String algorithm, String encoding){
OTPCredentialModel credentialModel = new OTPCredentialModel(secretValue, TOTP, digits, 0, period, algorithm, encoding);
credentialModel.fillCredentialModelFields();
return credentialModel;
}
public static OTPCredentialModel createHOTP(String secretValue, int digits, int counter, String algorithm) {
OTPCredentialModel credentialModel = new OTPCredentialModel(secretValue, HOTP, digits, counter, 0, algorithm);
credentialModel.fillCredentialModelFields();
return credentialModel;
}
public static OTPCredentialModel createFromPolicy(RealmModel realm, String secretValue) {
return createFromPolicy(realm, secretValue, "");
}
public static OTPCredentialModel createFromPolicy(RealmModel realm, String secretValue, String userLabel) {
OTPPolicy policy = realm.getOTPPolicy();
OTPCredentialModel credentialModel = new OTPCredentialModel(secretValue, policy.getType(), policy.getDigits(),
policy.getInitialCounter(), policy.getPeriod(), policy.getAlgorithm());
credentialModel.fillCredentialModelFields();
credentialModel.setUserLabel(userLabel);
return credentialModel;
}
public static OTPCredentialModel createFromCredentialModel(CredentialModel credentialModel) {
try {
OTPCredentialData credentialData = JsonSerialization.readValue(credentialModel.getCredentialData(), OTPCredentialData.class);
OTPSecretData secretData = JsonSerialization.readValue(credentialModel.getSecretData(), OTPSecretData.class);
OTPCredentialModel otpCredentialModel = new OTPCredentialModel(credentialData, secretData);
otpCredentialModel.setUserLabel(credentialModel.getUserLabel());
otpCredentialModel.setCreatedDate(credentialModel.getCreatedDate());
otpCredentialModel.setType(TYPE);
otpCredentialModel.setId(credentialModel.getId());
otpCredentialModel.setSecretData(credentialModel.getSecretData());
otpCredentialModel.setCredentialData(credentialModel.getCredentialData());
return otpCredentialModel;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void updateCounter(int counter) {
credentialData.setCounter(counter);
try {
setCredentialData(JsonSerialization.writeValueAsString(credentialData));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public OTPCredentialData getOTPCredentialData() {
return credentialData;
}
public OTPSecretData getOTPSecretData() {
return secretData;
}
public byte[] getDecodedSecret() {
String encoding = credentialData.getSecretEncoding();
if (encoding == null) {
return secretData.getValue().getBytes(StandardCharsets.UTF_8);
}
try {
if (SecretEncoding.BASE32.equals(SecretEncoding.valueOf(encoding.toUpperCase()))) {
return Base32.decode(secretData.getValue());
}
throw new RuntimeException("Unsupported secret encoding: " + encoding);
} catch (Exception cause) {
throw new RuntimeException("Failed to decode otp secret using encoding [" + encoding + "]", cause);
}
}
private void fillCredentialModelFields(){
try {
setCredentialData(JsonSerialization.writeValueAsString(credentialData));
setSecretData(JsonSerialization.writeValueAsString(secretData));
setType(TYPE);
setCreatedDate(Time.currentTimeMillis());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}