package io.cattle.platform.iaas.api.filter.apikey; import io.cattle.platform.archaius.util.ArchaiusUtil; import io.cattle.platform.core.constants.CredentialConstants; import io.cattle.platform.core.model.Credential; import io.cattle.platform.iaas.api.filter.common.AbstractDefaultResourceManagerFilter; import io.github.ibuildthecloud.gdapi.context.ApiContext; import io.github.ibuildthecloud.gdapi.request.ApiRequest; import io.github.ibuildthecloud.gdapi.request.resource.ResourceManager; import java.security.SecureRandom; import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Hex; import com.netflix.config.DynamicStringProperty; public class ApiKeyFilter extends AbstractDefaultResourceManagerFilter { public static final DynamicStringProperty BAD_CHARACTERS = ArchaiusUtil.getString("process.credential.create.bad.characters"); private final static SecureRandom RANDOM = new SecureRandom(); @Override public String[] getTypes() { return new String[] {CredentialConstants.KIND_API_KEY}; } @Override public Object create(String type, ApiRequest request, ResourceManager next) { Credential cred = request.proxyRequestObject(Credential.class); if (cred.getPublicValue() == null) { String[] keys = generateKeys(); cred.setPublicValue(keys[0]); cred.setSecretValue(keys[1]); } String clearSecret = cred.getSecretValue(); if (clearSecret != null) { cred.setSecretValue(ApiContext.getContext().getTransformationService().transform(clearSecret, "HASH")); } cred = (Credential) super.create(type, request, next); cred.setSecretValue(clearSecret); return cred; } public static String[] generateKeys() { byte[] accessKey = new byte[10]; byte[] secretKey = new byte[128]; RANDOM.nextBytes(accessKey); RANDOM.nextBytes(secretKey); String accessKeyString = Hex.encodeHexString(accessKey); String secretKeyString = Base64.encodeBase64String(secretKey).replaceAll(BAD_CHARACTERS.get(), ""); if (secretKeyString.length() < 40) { /* Wow, this is terribly bad luck */ throw new IllegalStateException("Failed to create secretKey due to not enough good characters"); } return new String[] { accessKeyString.substring(0, 20).toUpperCase(), secretKeyString.substring(0, 40) }; } }