nl.praegus.fitnesse.slim.fixtures.totp.TotpFixture Maven / Gradle / Ivy
Show all versions of toolchain-fixtures Show documentation
package nl.praegus.fitnesse.slim.fixtures.totp;
import com.warrenstrange.googleauth.GoogleAuthenticator;
import com.warrenstrange.googleauth.GoogleAuthenticatorConfig;
import nl.hsac.fitnesse.fixture.slim.SlimFixture;
import nl.hsac.fitnesse.fixture.slim.SlimFixtureException;
/**
* This fixture generates a Time-bases One Time Password (TOPT). That is the same code that is generated by e.g.
* the Google Authenticator app. The fixture uses the library found on https://github.com/wstrange/GoogleAuth.
*
* In order to get a correct TOTP you need:
* - the secret. Generally this is encoded in the QR code. Many platforms, however, also have options to show the
* unencoded secret in order to manually add an account to your authenticator app. This unencoded secret is needed by
* this fixture in order to generate the TOTP
* - The machine executing the fixture should have the time set correctly. Practically this means that its time should
* be synced with a NTP server.
*/
public class TotpFixture extends SlimFixture {
private final GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder configBuilder
= new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder();
private String secretKey = null;
/**
* Default constructor. Set secret key using setSecretKey or call getTotpForSecret(secretKey) to generate a OTP.
*/
public TotpFixture() {
}
/**
* Constructor with secretkey
*
* @param secretKey secretKey to generate OTP's
*/
public TotpFixture(String secretKey) {
setSecretKey(secretKey);
}
/**
* Set the number of digits to expect as the returned TOTP. Can be 6, 7 or 8
*
* @param numberOfDigits The number of digits. Defaults to 6
*/
public void setNumberOfDigits(int numberOfDigits) {
if (numberOfDigits < 6 || numberOfDigits > 8) {
throw new SlimFixtureException("TOTP length needs to be > 6 and < 8");
}
configBuilder.setCodeDigits(numberOfDigits);
}
/**
* Set the secret to generate the code for
*
* @param secretKey The key to use, as string
*/
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
/**
* Generate a OTP based on the secret that was set before
*
* @return OTP as 6-8 digit String
*/
public String getTotp() {
return getTotpForSecret(secretKey);
}
/**
* Generate a OTP based on a given secret key
*
* @param secretKey The secret key to generate OTP for
* @return OTP as 6-8 digit String
*/
public String getTotpForSecret(String secretKey) {
if (null == secretKey) {
throw new SlimFixtureException("No secret key was provided to generate OTP with");
}
GoogleAuthenticatorConfig gAuthConfig = configBuilder.build();
GoogleAuthenticator gAuth = new GoogleAuthenticator(gAuthConfig);
int totp = gAuth.getTotpPassword(secretKey);
/**
* GoogleAuthenticator returns code as an int and so can't have leading zeros. This means that the generated code
* can have a length shorter than the configured length (defaults to 6). This is solved by adding leading zero's
*/
return TotpUtils.padCodeWithZerosToNumberOfDigits(totp, gAuthConfig.getCodeDigits());
}
}