package net.thucydides.core.reports.saucelabs; import com.google.inject.Inject; import net.thucydides.core.ThucydidesSystemProperty; import net.thucydides.core.model.TestOutcome; import net.thucydides.core.util.EnvironmentVariables; import org.apache.commons.codec.binary.Hex; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.security.GeneralSecurityException; import java.security.Key; /** * Used to generate links to Saucelabs videos when the tests are executed on the Saucelabs servers. */ public class SaucelabsLinkGenerator implements LinkGenerator { private EnvironmentVariables environmentVariables; //no arg constructor for serialization public SaucelabsLinkGenerator() { } @Inject public SaucelabsLinkGenerator(EnvironmentVariables environmentVariables) { this.environmentVariables = environmentVariables; } public String linkFor(TestOutcome testOutcome) { String jobId = testOutcome.getSessionId(); if (jobId == null) { return null; } if (accessKeyAvailable()) { return noLoginLinkFor(jobId); } else { return simpleLinkFor(jobId); } } private String simpleLinkFor(String jobId) { return "http://saucelabs.com/jobs/" + jobId; } private String noLoginLinkFor(String jobId) { String accessKey = ThucydidesSystemProperty.SAUCELABS_ACCESS_KEY.from(environmentVariables); String username = ThucydidesSystemProperty.SAUCELABS_USER_ID.from(environmentVariables); String authCode = generateHMACFor(username + ":" + accessKey, jobId); return "https://saucelabs.com/jobs/" + jobId + "?auth=" + authCode; } private String generateHMACFor(String secretKey, String message) { try { byte[] keyBytes = secretKey.getBytes(); Key key = new SecretKeySpec(keyBytes, 0, keyBytes.length, "HmacMD5"); Mac mac = Mac.getInstance("HmacMD5"); mac.init(key); return new String(Hex.encodeHex(mac.doFinal(message.getBytes()))); } catch (GeneralSecurityException e) { throw new IllegalStateException("Could not generate HMAC for some reason", e); } } private boolean accessKeyAvailable() { return ThucydidesSystemProperty.SAUCELABS_ACCESS_KEY.from(environmentVariables) != null; } }