use of io.hops.hopsworks.persistence.entity.user.security.secrets.Secret in project hopsworks by logicalclocks.
the class SecretsController method get.
/**
* Gets a decrypted Secret
* @param user The user associated with the secret
* @param secretName The Secret identifier
* @return The Secret decrypted along with some metadata
* @throws UserException
*/
public SecretPlaintext get(Users user, String secretName) throws UserException {
checkIfUserIsNull(user);
checkIfNameIsNullOrEmpty(secretName);
SecretId id = new SecretId(user.getUid(), secretName);
Secret storedSecret = secretsFacade.findById(id);
checkIfSecretIsNull(storedSecret, secretName, user);
try {
return decrypt(user, storedSecret);
} catch (IOException | GeneralSecurityException ex) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_ENCRYPTION_ERROR, Level.SEVERE, "Error decrypting Secret", "Could not decrypt Secret " + secretName, ex);
}
}
use of io.hops.hopsworks.persistence.entity.user.security.secrets.Secret in project hopsworks by logicalclocks.
the class SecretsController method validateAndCreateSecret.
/**
* Validates parameters required to create a secret and creates the secret
*
* @param secretId combination of userId and secretName
* @param user
* @param secret in plain text
* @param visibilityType
* @param projectIdScope
* @return created secret object
* @throws UserException
*/
public Secret validateAndCreateSecret(SecretId secretId, Users user, String secret, VisibilityType visibilityType, Integer projectIdScope) throws UserException {
checkIfUserIsNull(user);
checkIfNameIsNullOrEmpty(secretId.getName());
if (Strings.isNullOrEmpty(secretId.getName()) || Strings.isNullOrEmpty(secret)) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_EMPTY, Level.FINE, "Secret value is either null or empty", "Secret name or value is empty or null");
}
try {
Secret storedSecret = new Secret(secretId, encryptSecret(secret), DateUtils.localDateTime2Date(DateUtils.getNow()));
storedSecret.setVisibilityType(visibilityType);
if (visibilityType.equals(VisibilityType.PRIVATE)) {
// When the user adds secrets without closing the UI modal
// they might change visibility to Private but a Project from
// the previous attempt is still selected
storedSecret.setProjectIdScope(null);
} else {
if (projectIdScope == null) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_EMPTY, Level.FINE, "Secret visibility is PROJECT but there is not Project ID scope", "Project scope for shared secret " + secretId.getName() + " is null");
}
if (projectFacade.find(projectIdScope) == null) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_EMPTY, Level.FINE, "Could not find a project for Project ID scope " + projectIdScope);
}
storedSecret.setProjectIdScope(projectIdScope);
}
return storedSecret;
} catch (IOException | GeneralSecurityException ex) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_ENCRYPTION_ERROR, Level.SEVERE, "Error encrypting secret", "Could not encrypt Secret " + secretId.getName(), ex);
}
}
use of io.hops.hopsworks.persistence.entity.user.security.secrets.Secret in project hopsworks by logicalclocks.
the class SecretsController method getShared.
/**
* Gets a decrypted shared secret depending on its Visibility. It will throw an exception
* if the Visibility was set to PRIVATE or the caller is not member of the Project
* the Secret is shared with.
*
* @param caller The user who requested the Secret
* @param ownerUser the user owner of the secret
* @param secretName Identifier of the Secret
* @return The decrypted Secret
* @throws UserException
* @throws ServiceException
* @throws ProjectException
*/
public SecretPlaintext getShared(Users caller, Users ownerUser, String secretName) throws UserException, ServiceException, ProjectException {
checkIfUserIsNull(caller);
checkIfNameIsNullOrEmpty(secretName);
checkIfUserIsNull(ownerUser);
Secret storedSecret = secretsFacade.findById(new SecretId(ownerUser.getUid(), secretName));
checkIfSecretIsNull(storedSecret, secretName, ownerUser);
if (storedSecret.getVisibilityType() == null || storedSecret.getVisibilityType().equals(VisibilityType.PRIVATE)) {
throw new UserException(RESTCodes.UserErrorCode.ACCESS_CONTROL, Level.FINE, "Secret is Private", "User " + caller.getUsername() + " requested PRIVATE secret <" + ownerUser.getUid() + ", " + secretName + ">");
}
Integer projectId = storedSecret.getProjectIdScope();
if (projectId == null) {
throw new ServiceException(RESTCodes.ServiceErrorCode.SERVICE_GENERIC_ERROR, Level.WARNING, "Visibility's Project ID is empty", "Secret " + secretName + " visibility is PROJECT but Project ID is null");
}
Project project = projectFacade.find(projectId);
if (project == null) {
throw new ProjectException(RESTCodes.ProjectErrorCode.PROJECT_NOT_FOUND, Level.FINE, "Project with ID " + projectId + " does not exist!", "User " + caller.getUsername() + " requested shared Secret " + secretName + " but Project with ID " + projectId + "does not exist");
}
// Check if caller is member of the Project
for (ProjectTeam projectTeam : project.getProjectTeamCollection()) {
if (caller.getUid().equals(projectTeam.getUser().getUid())) {
try {
return decrypt(ownerUser, storedSecret);
} catch (IOException | GeneralSecurityException ex) {
throw new UserException(RESTCodes.UserErrorCode.SECRET_ENCRYPTION_ERROR, Level.SEVERE, "Error decrypting Secret", "Could not decrypt Secret " + secretName, ex);
}
}
}
// Check if caller is a member of some shared project
throw new UserException(RESTCodes.UserErrorCode.ACCESS_CONTROL, Level.FINE, "Not authorized to access Secret " + secretName, "User " + caller.getUsername() + " tried to access shared Secret " + secretName + " but they are not member of Project " + project.getName());
}
use of io.hops.hopsworks.persistence.entity.user.security.secrets.Secret in project hopsworks by logicalclocks.
the class SecretsPasswordHandler method rollback.
@Override
@SuppressWarnings("unchecked")
public void rollback(MasterPasswordChangeResult result) {
Map<SecretId, byte[]> secrets2rollback = (HashMap<SecretId, byte[]>) result.getRollbackItems();
LOGGER.log(Level.INFO, "Rolling back Secrets");
Secret secret;
for (Map.Entry<SecretId, byte[]> secret2rollback : secrets2rollback.entrySet()) {
Secret persistedSecret = secretsFacade.findById(secret2rollback.getKey());
if (persistedSecret == null) {
continue;
}
secret = new Secret(secret2rollback.getKey(), secret2rollback.getValue(), persistedSecret.getAddedOn());
secret.setVisibilityType(persistedSecret.getVisibilityType());
if (persistedSecret.getProjectIdScope() != null) {
secret.setProjectIdScope(persistedSecret.getProjectIdScope());
}
secretsFacade.update(secret);
}
}
use of io.hops.hopsworks.persistence.entity.user.security.secrets.Secret in project hopsworks by logicalclocks.
the class SecretsPasswordHandler method perform.
@Override
public MasterPasswordChangeResult perform(String oldPassword, String newPassword) {
Map<SecretId, byte[]> secrets2Rollback = new HashMap<>();
StringBuilder successLog = new StringBuilder();
successLog.append("Performing change of master password for Secrets\n");
SecretId secretId;
Secret newSecret;
SymmetricEncryptionDescriptor inDescriptor;
SymmetricEncryptionDescriptor outDescriptor;
try {
LOGGER.log(Level.INFO, "Updating Secrets with new Hopsworks master encryption password");
List<Secret> cipheredSecrets = secretsController.getAllCiphered();
for (Secret cipheredSecret : cipheredSecrets) {
secretId = cipheredSecret.getId();
secrets2Rollback.put(secretId, cipheredSecret.getSecret());
// First decrypt with the old password
byte[][] cryptoPrimitives = symmetricEncryptionService.splitPayloadFromCryptoPrimitives(cipheredSecret.getSecret());
inDescriptor = new SymmetricEncryptionDescriptor.Builder().setPassword(oldPassword).setSalt(cryptoPrimitives[0]).setIV(cryptoPrimitives[1]).setInput(cryptoPrimitives[2]).build();
outDescriptor = symmetricEncryptionService.decrypt(inDescriptor);
inDescriptor.clearPassword();
// Then encrypt plaintext secret with the new password
inDescriptor = new SymmetricEncryptionDescriptor.Builder().setInput(outDescriptor.getOutput()).setPassword(newPassword).build();
outDescriptor = symmetricEncryptionService.encrypt(inDescriptor);
inDescriptor.clearPassword();
byte[] newCipheredSecret = symmetricEncryptionService.mergePayloadWithCryptoPrimitives(outDescriptor.getSalt(), outDescriptor.getIv(), outDescriptor.getOutput());
// Store new API key
newSecret = new Secret(secretId, newCipheredSecret, cipheredSecret.getAddedOn());
newSecret.setVisibilityType(cipheredSecret.getVisibilityType());
if (cipheredSecret.getProjectIdScope() != null) {
newSecret.setProjectIdScope(cipheredSecret.getProjectIdScope());
}
secretsFacade.update(newSecret);
successLog.append("Updated Secret <").append(newSecret.getId().getUid()).append(",").append(newSecret.getId().getName()).append(">\n");
}
return new MasterPasswordChangeResult<>(successLog, secrets2Rollback, null);
} catch (Exception ex) {
String errorMsg = "Error while updating master encryption password for Secrets";
LOGGER.log(Level.SEVERE, errorMsg, ex);
return new MasterPasswordChangeResult<>(secrets2Rollback, new EncryptionMasterPasswordException(errorMsg, ex));
}
}
Aggregations