Search in sources :

Example 66 with ConcordApplicationException

use of com.walmartlabs.concord.server.sdk.ConcordApplicationException in project concord by walmartlabs.

the class SecretResource method update.

@POST
// weird URLs as a workaround for swagger-maven-plugin issue
@ApiOperation("Updates an existing secret")
@Path("/{orgName}/secret/{secretName}")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Validate
@Deprecated
public GenericOperationResult update(@ApiParam @PathParam("orgName") @ConcordKey String orgName, @ApiParam @PathParam("secretName") @ConcordKey String secretName, @ApiParam @Valid SecretUpdateRequest req) {
    OrganizationEntry org = orgManager.assertAccess(orgName, true);
    try {
        SecretUpdateParams newSecretParams = SecretUpdateParams.builder().newOrgId(req.orgId()).newOrgName(req.orgName()).newProjectId(req.projectId()).newProjectName(req.projectName()).removeProjectLink(req.projectName() != null && req.projectName().trim().isEmpty()).newOwnerId(getOwnerId(req.owner())).currentPassword(req.storePassword()).newPassword(req.newStorePassword()).newSecret(req.data() != null ? secretManager.buildBinaryData(new ByteArrayInputStream(Objects.requireNonNull(req.data()))) : null).newName(req.name()).newVisibility(req.visibility()).build();
        secretManager.update(org.getId(), secretName, newSecretParams);
    } catch (IOException e) {
        throw new ConcordApplicationException("Error while processing the request: " + e.getMessage(), e);
    }
    return new GenericOperationResult(OperationResult.UPDATED);
}
Also used : GenericOperationResult(com.walmartlabs.concord.server.GenericOperationResult) ByteArrayInputStream(java.io.ByteArrayInputStream) ConcordApplicationException(com.walmartlabs.concord.server.sdk.ConcordApplicationException) IOException(java.io.IOException) Validate(org.sonatype.siesta.Validate)

Example 67 with ConcordApplicationException

use of com.walmartlabs.concord.server.sdk.ConcordApplicationException in project concord by walmartlabs.

the class PolicyResource method assertLink.

private PolicyLink assertLink(String policyName, String orgName, String projectName, String userName, String domain, UserType userType) {
    UUID policyId = policyManager.getId(policyName);
    if (policyId == null) {
        throw new ConcordApplicationException("Policy not found: " + policyName, Status.NOT_FOUND);
    }
    UUID orgId = null;
    if (orgName != null) {
        OrganizationEntry org = orgManager.assertAccess(orgName, true);
        orgId = org.getId();
    }
    UUID projectId = null;
    if (projectName != null) {
        if (orgId != null) {
            projectId = assertProject(orgId, projectName);
        } else {
            throw new ConcordApplicationException("Organization name is required", Status.BAD_REQUEST);
        }
    }
    if (projectId != null) {
        // projectId is enough to make a proper reference
        orgId = null;
    }
    UUID userId = null;
    if (userName != null && userType != null) {
        userId = assertUser(userName, domain, userType);
    }
    return new PolicyLink(policyId, orgId, projectId, userId);
}
Also used : ConcordApplicationException(com.walmartlabs.concord.server.sdk.ConcordApplicationException) UUID(java.util.UUID) OrganizationEntry(com.walmartlabs.concord.server.org.OrganizationEntry)

Example 68 with ConcordApplicationException

use of com.walmartlabs.concord.server.sdk.ConcordApplicationException in project concord by walmartlabs.

the class SecretResourceV2 method update.

@POST
@ApiOperation("Updates an existing secret")
@Path("/{orgName}/secret/{secretName}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
@Validate
public GenericOperationResult update(@ApiParam @PathParam("orgName") @ConcordKey String orgName, @ApiParam @PathParam("secretName") @ConcordKey String secretName, @ApiParam MultipartInput input) {
    OrganizationEntry org = orgManager.assertAccess(orgName, true);
    try {
        SecretUpdateParams newSecretParams = SecretUpdateParams.builder().newOrgId(MultipartUtils.getUuid(input, Constants.Multipart.ORG_ID)).newOrgName(MultipartUtils.getString(input, Constants.Multipart.ORG_NAME)).newProjectId(MultipartUtils.getUuid(input, Constants.Multipart.PROJECT_ID)).newProjectName(MultipartUtils.getString(input, Constants.Multipart.PROJECT_NAME)).removeProjectLink(MultipartUtils.getBoolean(input, "removeProjectLink", false)).newOwnerId(MultipartUtils.getUuid(input, "ownerId")).currentPassword(MultipartUtils.getString(input, Constants.Multipart.STORE_PASSWORD)).newPassword(MultipartUtils.getString(input, "newStorePassword")).newSecret(buildSecret(input)).newName(MultipartUtils.getString(input, Constants.Multipart.NAME)).newVisibility(getVisibility(input)).build();
        secretManager.update(org.getId(), secretName, newSecretParams);
    } catch (IOException e) {
        throw new ConcordApplicationException("Error while processing the request: " + e.getMessage(), e);
    }
    return new GenericOperationResult(OperationResult.UPDATED);
}
Also used : GenericOperationResult(com.walmartlabs.concord.server.GenericOperationResult) ConcordApplicationException(com.walmartlabs.concord.server.sdk.ConcordApplicationException) IOException(java.io.IOException) OrganizationEntry(com.walmartlabs.concord.server.org.OrganizationEntry) Validate(org.sonatype.siesta.Validate) ApiOperation(io.swagger.annotations.ApiOperation)

Example 69 with ConcordApplicationException

use of com.walmartlabs.concord.server.sdk.ConcordApplicationException in project concord by walmartlabs.

the class OidcRealm method doGetAuthenticationInfo.

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    OidcToken t = (OidcToken) token;
    OidcProfile profile = t.getProfile();
    // TODO replace getOrCreate+update with a single method?
    String username = profile.getEmail().toLowerCase();
    UserEntry u = userManager.getOrCreate(username, null, UserType.LOCAL).orElseThrow(() -> new ConcordApplicationException("User not found: " + profile.getEmail()));
    userManager.update(u.getId(), profile.getDisplayName(), profile.getEmail(), null, false, null);
    UserPrincipal userPrincipal = new UserPrincipal(REALM_NAME, u);
    return new SimpleAccount(Arrays.asList(userPrincipal, t), t, getName());
}
Also used : SimpleAccount(org.apache.shiro.authc.SimpleAccount) ConcordApplicationException(com.walmartlabs.concord.server.sdk.ConcordApplicationException) OidcProfile(org.pac4j.oidc.profile.OidcProfile) UserEntry(com.walmartlabs.concord.server.user.UserEntry) UserPrincipal(com.walmartlabs.concord.server.security.UserPrincipal)

Example 70 with ConcordApplicationException

use of com.walmartlabs.concord.server.sdk.ConcordApplicationException in project concord by walmartlabs.

the class SecretManager method update.

/**
 * Updates name and/or visibility and/or data of an existing secret.
 */
public void update(String orgName, String secretName, SecretUpdateRequest req) {
    SecretEntry e;
    if (req.id() == null) {
        OrganizationEntry org = orgManager.assertAccess(null, orgName, false);
        e = assertAccess(org.getId(), null, secretName, ResourceAccessLevel.OWNER, true);
    } else {
        e = assertAccess(null, req.id(), null, ResourceAccessLevel.WRITER, true);
    }
    UserEntry owner = getOwner(req.owner(), null);
    policyManager.checkEntity(e.getOrgId(), req.projectId(), EntityType.SECRET, EntityAction.UPDATE, owner, PolicyUtils.secretToMap(e.getOrgId(), e.getName(), e.getType(), e.getVisibility(), e.getStoreType()));
    UUID currentOwnerId = e.getOwner() != null ? e.getOwner().id() : null;
    UUID updatedOwnerId = owner != null ? owner.getId() : null;
    if (updatedOwnerId != null && !updatedOwnerId.equals(currentOwnerId)) {
        OrganizationEntry org = orgManager.assertAccess(null, orgName, false);
        assertAccess(org.getId(), null, secretName, ResourceAccessLevel.OWNER, true);
    }
    String currentPassword = req.storePassword();
    String newPassword = req.newStorePassword();
    if (e.getEncryptedBy() == SecretEncryptedByType.SERVER_KEY && (currentPassword != null || newPassword != null)) {
        throw new ConcordApplicationException("The secret is encrypted with the server's key, the '" + Constants.Multipart.STORE_PASSWORD + "' cannot be changed", Status.BAD_REQUEST);
    }
    Map<String, Object> updated = new HashMap<>();
    byte[] newData = req.data();
    if (newData != null) {
        // updating the data and/or the store password
        if (e.getEncryptedBy() == SecretEncryptedByType.PASSWORD && currentPassword == null) {
            throw new ConcordApplicationException("Updating the secret's data requires the original '" + Constants.Multipart.STORE_PASSWORD + "'", Status.BAD_REQUEST);
        }
        if (e.getType() != SecretType.DATA) {
            throw new ConcordApplicationException("Can't update the data of a non-single value secret (current type: " + e.getType() + ")", Status.BAD_REQUEST);
        }
        // validate the current password
        decryptData(e.getId(), e.getStoreType(), currentPassword);
        updated.put("data", true);
    } else if (newPassword != null) {
        // keeping the old data, just changing the store password
        newData = decryptData(e.getId(), e.getStoreType(), currentPassword);
    }
    String pwd = currentPassword;
    if (newPassword != null && !newPassword.equals(currentPassword)) {
        pwd = req.newStorePassword();
        updated.put(Constants.Multipart.STORE_PASSWORD, true);
    }
    byte[] newEncryptedData;
    if (newData != null) {
        // encrypt the supplied data
        byte[] salt = secretCfg.getSecretStoreSalt();
        newEncryptedData = SecretUtils.encrypt(newData, getPwd(pwd), salt);
    } else {
        newEncryptedData = null;
    }
    OrganizationEntry organizationEntry = null;
    if (req.orgId() != null) {
        organizationEntry = orgManager.assertAccess(req.orgId(), true);
    } else if (req.orgName() != null) {
        organizationEntry = orgManager.assertAccess(req.orgName(), true);
    }
    UUID orgIdUpdate = organizationEntry != null ? organizationEntry.getId() : e.getOrgId();
    UUID effectiveProjectId = req.projectId();
    String effectiveProjectName = req.projectName();
    if (req.projectId() == null && req.projectName() == null) {
        effectiveProjectId = e.getProjectId();
        effectiveProjectName = e.getProjectName();
    }
    if (!orgIdUpdate.equals(e.getOrgId())) {
        // set the project ID and project name as null when the updated org ID is not same as the current org ID
        // when a secret is changing orgs, the project link must be set to null
        effectiveProjectId = null;
        effectiveProjectName = null;
    }
    if (req.projectName() != null && req.projectName().trim().isEmpty()) {
        // empty project name means "remove the project link"
        effectiveProjectId = null;
        effectiveProjectName = null;
    }
    if (effectiveProjectId != null || effectiveProjectName != null) {
        ProjectEntry entry = projectAccessManager.assertAccess(e.getOrgId(), effectiveProjectId, effectiveProjectName, ResourceAccessLevel.READER, true);
        effectiveProjectId = entry.getId();
        if (!entry.getOrgId().equals(e.getOrgId())) {
            throw new ValidationErrorsException("Project '" + entry.getName() + "' does not belong to organization '" + orgName + "'");
        }
    }
    UUID finalProjectId = effectiveProjectId;
    secretDao.tx(tx -> {
        if (!orgIdUpdate.equals(e.getOrgId())) {
            // update repository mapping to null when org is changing
            repositoryDao.clearSecretMappingBySecretId(tx, e.getId());
        }
        secretDao.update(tx, e.getId(), req.name(), updatedOwnerId, newEncryptedData, req.visibility(), finalProjectId, orgIdUpdate);
    });
    Map<String, Object> changes = DiffUtils.compare(e, secretDao.get(e.getId()));
    changes.put("updated", updated);
    auditLog.add(AuditObject.SECRET, AuditAction.UPDATE).field("orgId", e.getOrgId()).field("secretId", e.getId()).field("name", e.getName()).field("changes", changes).log();
}
Also used : ProjectEntry(com.walmartlabs.concord.server.org.project.ProjectEntry) ConcordApplicationException(com.walmartlabs.concord.server.sdk.ConcordApplicationException) UserEntry(com.walmartlabs.concord.server.user.UserEntry) AuditObject(com.walmartlabs.concord.server.audit.AuditObject) ValidationErrorsException(org.sonatype.siesta.ValidationErrorsException)

Aggregations

ConcordApplicationException (com.walmartlabs.concord.server.sdk.ConcordApplicationException)70 ApiOperation (io.swagger.annotations.ApiOperation)28 UUID (java.util.UUID)22 WithTimer (com.walmartlabs.concord.server.sdk.metrics.WithTimer)21 PartialProcessKey (com.walmartlabs.concord.server.sdk.PartialProcessKey)18 IOException (java.io.IOException)14 ValidationErrorsException (org.sonatype.siesta.ValidationErrorsException)12 GenericOperationResult (com.walmartlabs.concord.server.GenericOperationResult)11 ProcessKey (com.walmartlabs.concord.server.sdk.ProcessKey)11 Validate (org.sonatype.siesta.Validate)11 Path (java.nio.file.Path)10 UserPrincipal (com.walmartlabs.concord.server.security.UserPrincipal)9 OrganizationEntry (com.walmartlabs.concord.server.org.OrganizationEntry)8 EntryPoint (com.walmartlabs.concord.server.process.PayloadManager.EntryPoint)6 ProcessStatus (com.walmartlabs.concord.server.sdk.ProcessStatus)6 UnauthorizedException (org.apache.shiro.authz.UnauthorizedException)6 UserEntry (com.walmartlabs.concord.server.user.UserEntry)5 InputStream (java.io.InputStream)4 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 Form (com.walmartlabs.concord.forms.Form)3