Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCD-4705: Fixes related to uploading and confirming via file #1736

Open
wants to merge 12 commits into
base: staging
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,7 @@ public ResponseEntity<CertifiedProductSearchDetails> updateCertifiedProduct(
CertifiedProductSearchDetails existingListing = cpdManager.getCertifiedProductDetails(updatedListing.getId());
Long acbId = Long.parseLong(existingListing.getCertifyingBody().get(CertifiedProductSearchDetails.ACB_ID_KEY).toString());

// if the ACB owner is changed this is a separate action with different
// security
// if the ACB owner is changed this is a separate action with different security
Long newAcbId = Long
.valueOf(updatedListing.getCertifyingBody().get(CertifiedProductSearchDetails.ACB_ID_KEY).toString());
if (acbId.longValue() != newAcbId.longValue()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import gov.healthit.chpl.auth.jwt.JWTConsumer;
import gov.healthit.chpl.auth.user.JWTAuthenticatedUser;
import gov.healthit.chpl.dao.auth.UserDAO;
import gov.healthit.chpl.domain.auth.User;
import gov.healthit.chpl.exception.JWTValidationException;
import gov.healthit.chpl.exception.MultipleUserAccountsException;
import gov.healthit.chpl.exception.UserRetrievalException;
import gov.healthit.chpl.user.cognito.CognitoApiWrapper;
import lombok.extern.log4j.Log4j2;

Expand Down Expand Up @@ -38,7 +40,21 @@ public JWTAuthenticatedUser getAuthenticatedUser(String jwt) throws JWTValidatio
//If SSO is on, try to validate the jwt using the Cognito converter
if (ff4j.check(FeatureList.SSO)) {
user = cognitoJwtUserConverter.getAuthenticatedUser(jwt);
} else {
if (user != null) {
try {
//Set some values not avail in the Cognito Access Token that were avail in the CHPL token
User cognitoUser = cognitoApiWrapper.getUserInfo(user.getCognitoId());
user.setEmail(cognitoUser.getEmail());
user.setSubjectName(cognitoUser.getEmail());
user.setFullName(cognitoUser.getFullName());
} catch (UserRetrievalException e) {
throw new JWTValidationException("Could not locate the Cognito user id");
}
}
}

//If SSO is off or jwt cannot be converted using the Cognito converter, use the CHP converter
if (user == null) {
user = chplJwtUserConverter.getAuthenticatedUser(jwt);
}
return user;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public Map<String, Object> consume(String jwt) throws InvalidJwtException {
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
return jwtClaims.getClaimsMap();
} catch (InvalidJwtException e) {
LOGGER.error("Invalid JWT");
LOGGER.error("Invalid JWT", e);
throw e;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import gov.healthit.chpl.certificationCriteria.CertificationCriterionWithAttributes.AllowedAttributes;
import gov.healthit.chpl.dao.CertificationCriterionDAO;
import gov.healthit.chpl.domain.CertifiedProductSearchDetails;
import gov.healthit.chpl.permissions.ResourcePermissionsFactory;
import gov.healthit.chpl.util.CertificationResultRules;
import gov.healthit.chpl.util.DateUtil;
import lombok.extern.log4j.Log4j2;
Expand All @@ -26,14 +27,17 @@ public class CertificationCriteriaManager {
private CertificationCriterionDAO certificationCriterionDao;
private CertificationResultRules rules;
private CertificationCriterionComparator criterionComparator;
private ResourcePermissionsFactory resourcePermissionsFactory;

@Autowired
public CertificationCriteriaManager(CertificationCriterionDAO certificationCriterionDao,
CertificationResultRules rules,
CertificationCriterionComparator criterionComparator) {
CertificationCriterionComparator criterionComparator,
ResourcePermissionsFactory resourcePermissionsFactory) {
this.certificationCriterionDao = certificationCriterionDao;
this.rules = rules;
this.criterionComparator = criterionComparator;
this.resourcePermissionsFactory = resourcePermissionsFactory;
}

@Transactional
Expand Down Expand Up @@ -65,10 +69,10 @@ public List<CertificationCriterion> getActive(String certificationEdition, Local
.collect(Collectors.toList());
}

public List<CertificationCriterion> getCriteriaAvailableToListing(CertifiedProductSearchDetails listing) {
public List<CertificationCriterion> getCriteriaAvailableToListingAndUser(CertifiedProductSearchDetails listing) {
List<CertificationCriterion> allCriteriaAvailableToListing = Stream.concat(
getAttestedCriteria(listing).stream(),
getActiveCriteriaBasedOnEditionAndDate(listing).stream())
getEditableCriteria(listing).stream())
.distinct()
.sorted(criterionComparator)
.collect(Collectors.toList());
Expand All @@ -82,11 +86,18 @@ private List<CertificationCriterion> getAttestedCriteria(CertifiedProductSearchD
.collect(Collectors.toList());
}

private List<CertificationCriterion> getActiveCriteriaBasedOnEditionAndDate(CertifiedProductSearchDetails listing) {
private List<CertificationCriterion> getEditableCriteria(CertifiedProductSearchDetails listing) {
String edition = listing.getEdition() != null && !StringUtils.isEmpty(listing.getEdition().getName())
? listing.getEdition().getName() : null;

return this.getActive(edition, listing.getCertificationDay(), LocalDate.now());
List<CertificationCriterion> allActiveCriteria = this.getActive(edition, listing.getCertificationDay(), LocalDate.now());
if (!resourcePermissionsFactory.get().isUserRoleAdmin()
&& !resourcePermissionsFactory.get().isUserRoleOnc()) {
return allActiveCriteria.stream()
.filter(criterion -> criterion.isEditable())
.collect(Collectors.toList());
}
return allActiveCriteria;
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ public List<List<String>> getCsvData(CertifiedProductSearchDetails listing, int
}

private List<CertificationResult> getAllAvailableCriteriaAsCertResults(CertifiedProductSearchDetails listing) {
List<CertificationCriterion> allCriteriaAvailableToListing = criteriaManager.getCriteriaAvailableToListing(listing);
List<CertificationCriterion> allCriteriaAvailableToListing = criteriaManager.getCriteriaAvailableToListingAndUser(listing);
List<CertificationResult> allAvailableCriteriaAsCertResults = new ArrayList<CertificationResult>();
allCriteriaAvailableToListing.stream()
.forEach(criterion -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public List<String> getCsvHeadings(CertifiedProductSearchDetails listing) {

private List<String> getCriteriaHeadings(CertifiedProductSearchDetails listing) {
List<String> criteriaHeadings = new ArrayList<String>();
List<CertificationCriterion> allCriteriaAvailableToListing = criteriaManager.getCriteriaAvailableToListing(listing);
List<CertificationCriterion> allCriteriaAvailableToListing = criteriaManager.getCriteriaAvailableToListingAndUser(listing);
allCriteriaAvailableToListing.stream()
.forEach(certResult -> criteriaHeadings.addAll(getCriterionHeadings(certResult)));
return criteriaHeadings;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
Expand Down Expand Up @@ -252,8 +253,15 @@ private void setIdsForSed(CertifiedProductSed updatedListingSed, CertifiedProduc
if (!CollectionUtils.isEmpty(updatedListingSed.getTestTasks())) {
updatedListingSed.getTestTasks().stream()
.forEach(updatedTestTask -> setIdForTestTask(updatedTestTask, currListingSed.getTestTasks()));
}

Set<TestParticipant> currentTestParticipants = currListingSed.getTestTasks().stream()
.flatMap(currTestTask -> currTestTask.getTestParticipants().stream())
.collect(Collectors.toSet());

updatedListingSed.getTestTasks().stream()
.flatMap(updatedTestTask -> updatedTestTask.getTestParticipants().stream())
.forEach(updatedTestParticipant -> setIdForTestParticipant(updatedTestParticipant, currentTestParticipants));
}
}

private void setIdForTestTask(TestTask updatedTestTask, List<TestTask> currTestTasks) {
Expand All @@ -267,10 +275,6 @@ private void setIdForTestTask(TestTask updatedTestTask, List<TestTask> currTestT
.orElse(null);
if (matchedCurrTestTask != null) {
updatedTestTask.setId(matchedCurrTestTask.getId());
if (!CollectionUtils.isEmpty(updatedTestTask.getTestParticipants())) {
updatedTestTask.getTestParticipants().stream()
.forEach(updatedTestParticipant -> setIdForTestParticipant(updatedTestParticipant, matchedCurrTestTask.getTestParticipants()));
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public CertifiedProductTestingLab lookupMapping(Long certifiedProductId, Long tl
private CertifiedProductTestingLabMapEntity getEntityById(final Long id) throws EntityRetrievalException {
CertifiedProductTestingLabMapEntity entity = null;
Query query = entityManager.createQuery(
"SELECT tl from CertifiedProductTestingLabMapEntity tl "
+ "LEFT OUTER JOIN FETCH tl.testingLab "
+ "WHERE (NOT tl.deleted = true) "
+ "AND (id = :entityid) ",
"SELECT tlm from CertifiedProductTestingLabMapEntity tlm "
+ "LEFT OUTER JOIN FETCH tlm.testingLab "
+ "WHERE (NOT tlm.deleted = true) "
+ "AND (tlm.id = :entityid) ",
CertifiedProductTestingLabMapEntity.class);

query.setParameter("entityid", id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ public List<CertifiedProductDetailsDTO> getByProduct(Long productId) throws Enti
return cpDao.getDetailsByProductId(productId);
}

@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_ONC')")
@PreAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).CERTIFIED_PRODUCT, "
+ "T(gov.healthit.chpl.permissions.domains.CertifiedProductDomainPermissions).CHANGE_ACB_OWNER)")
@Transactional(readOnly = false)
@CacheEvict(value = {
CacheNames.GET_DECERTIFIED_DEVELOPERS, CacheNames.COLLECTIONS_DEVELOPERS
Expand Down Expand Up @@ -421,15 +422,15 @@ private void deleteCertifiedProductTestingLab(CertifiedProductTestingLab toDelet
try {
cpTestingLabDao.deleteCertifiedProductTestingLab(toDelete.getId());
} catch (Exception e) {
LOGGER.info("Could not delete CertifiedProductTestingLab with Id: {}, {}", toDelete.getId(), e.getMessage(), e);
LOGGER.error("Could not delete CertifiedProductTestingLab with Id: {}, {}", toDelete.getId(), e.getMessage(), e);
}
}

private void addCertifiedProductTestingLab(CertifiedProductTestingLab toAdd, Long listingId) {
try {
cpTestingLabDao.createCertifiedProductTestingLab(toAdd, listingId);
} catch (Exception e) {
LOGGER.info("Could not add CertifiedProductTestingLab with Id: {}, for Listing: {}, {}", toAdd.getTestingLab().getId(), listingId, e.getMessage(), e);
LOGGER.error("Could not add CertifiedProductTestingLab with Id: {}, for Listing: {}, {}", toAdd.getTestingLab().getId(), listingId, e.getMessage(), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,8 @@ public ChplJob updateJob(ChplJob job) throws SchedulerException {
}
}

@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_ONC')")
@PreAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).CERTIFICATION_BODY, "
+ "T(gov.healthit.chpl.permissions.domains.CertificationBodyDomainPermissions).RETIRE)")
public void retireAcb(String acb) throws SchedulerException, ValidationException, EmailNotSentException {
List<ChplRepeatableTrigger> allTriggers = getAllTriggersForUser();
for (ChplRepeatableTrigger trigger : allTriggers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public CHPLFilesManagerImpl(final CHPLFileDAO chplFileDAO) {

@Override
@Transactional
@PreAuthorize("hasAnyRole('ROLE_ADMIN', 'ROLE_ONC')")
@PreAuthorize("@permissions.hasAccess(T(gov.healthit.chpl.permissions.Permissions).API_DOCUMENTATION, "
+ "T(gov.healthit.chpl.permissions.domains.ApiDocumentationDomainPermissions).CREATE)")
public CHPLFileDTO addApiDocumentationFile(final CHPLFileDTO newFileDTO)
throws EntityCreationException, EntityRetrievalException {
// Need to delete the existing 'current' file
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

@Component
public class Permissions {
public static final String API_DOCUMENTATION = "API_DOCUMENTATION";
public static final String CERTIFICATION_RESULTS = "CERTIFICATION_RESULTS";
public static final String CERTIFIED_PRODUCT = "CERTIFIED_PRODUCT";
public static final String CORRECTIVE_ACTION_PLAN = "CORRECTIVE_ACTION_PLAN";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package gov.healthit.chpl.permissions.domains;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import gov.healthit.chpl.permissions.domains.apiDocumentation.CreateActionPermissions;

@Component
public class ApiDocumentationDomainPermissions extends DomainPermissions {
public static final String CREATE = "CREATE";

@Autowired
public ApiDocumentationDomainPermissions(
@Qualifier("apiDocumentationCreateActionPermissions") CreateActionPermissions createActionPermissions) {
getActionPermissions().put(CREATE, createActionPermissions);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import gov.healthit.chpl.permissions.domains.certifiedproduct.ChangeAcbOwnerActionPermissions;
import gov.healthit.chpl.permissions.domains.certifiedproduct.ConvertToCsvActionPermissions;
import gov.healthit.chpl.permissions.domains.certifiedproduct.CreateActionPermissions;
import gov.healthit.chpl.permissions.domains.certifiedproduct.UpdateActionPermissions;
Expand All @@ -17,18 +18,21 @@ public class CertifiedProductDomainPermissions extends DomainPermissions {
public static final String CREATE = "CREATE";
public static final String UPDATE = "UPDATE";
public static final String CONVERT_TO_CSV = "CONVERT_TO_CSV";
public static final String CHANGE_ACB_OWNER = "CHANGE_ACB_OWNER";

@Autowired
public CertifiedProductDomainPermissions(
@Qualifier("certifiedProductUploadActionPermissions") UploadActionPermissions uploadActionPermissions,
@Qualifier("certifiedProductUploadPiuActionPermissions") UploadPiuActionPermissions uploadPiuActionPermissions,
@Qualifier("certifiedProductCreateActionPermissions") CreateActionPermissions createActionPermissions,
@Qualifier("certifiedProductUpdateActionPermissions") UpdateActionPermissions updateActionPermissions,
@Qualifier("certifiedProductConvertToCsvActionPermissions") ConvertToCsvActionPermissions convertToCsvActionPermissions) {
@Qualifier("certifiedProductConvertToCsvActionPermissions") ConvertToCsvActionPermissions convertToCsvActionPermissions,
@Qualifier("certifiedProductChangeAcbOwnerActionPermissions") ChangeAcbOwnerActionPermissions changeAcbOwnerActionPermissions) {
getActionPermissions().put(UPLOAD, uploadActionPermissions);
getActionPermissions().put(UPLOAD_PIU, uploadPiuActionPermissions);
getActionPermissions().put(CREATE, createActionPermissions);
getActionPermissions().put(UPDATE, updateActionPermissions);
getActionPermissions().put(CONVERT_TO_CSV, convertToCsvActionPermissions);
getActionPermissions().put(CHANGE_ACB_OWNER, changeAcbOwnerActionPermissions);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gov.healthit.chpl.permissions.domains.apiDocumentation;

import org.springframework.stereotype.Component;

import gov.healthit.chpl.permissions.domains.ActionPermissions;

@Component("apiDocumentationCreateActionPermissions")
public class CreateActionPermissions extends ActionPermissions {

@Override
public boolean hasAccess() {
return getResourcePermissions().isUserRoleAdmin()
|| getResourcePermissions().isUserRoleOnc();
}

@Override
public boolean hasAccess(Object obj) {
return false;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package gov.healthit.chpl.permissions.domains.certifiedproduct;

import org.springframework.stereotype.Component;

import gov.healthit.chpl.permissions.domains.ActionPermissions;

@Component("certifiedProductChangeAcbOwnerActionPermissions")
public class ChangeAcbOwnerActionPermissions extends ActionPermissions {

@Override
public boolean hasAccess() {
return getResourcePermissions().isUserRoleAdmin()
|| getResourcePermissions().isUserRoleOnc();
}

@Override
public boolean hasAccess(Object obj) {
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public BaselineStandardAsOfCertificationDayNormalizer(BaselineStandardService ba
}

public LocalDate getStandardsCheckDate(CertifiedProductSearchDetails listing) {
return listing.getCertificationDay();
return listing.getCertificationDay() == null ? LocalDate.MIN : listing.getCertificationDay();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ public CodeSetAsOfCertificationDayReviewer(CertificationResultRules certResultRu
}

public LocalDate getCodeSetCheckDate(CertifiedProductSearchDetails listing) {
return listing.getCertificationDay();
return listing.getCertificationDay() == null ? LocalDate.MIN : listing.getCertificationDay();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ private void reviewFunctionalityTestedAvailabilityAfterListingActiveDates(Certif
}

private boolean isFunctionalityTestedRetiredBeforeListingActiveDates(CertifiedProductSearchDetails listing, FunctionalityTested functionalityTested) {
LocalDate listingStartDay = listing.getCertificationDay();
LocalDate listingStartDay = listing.getCertificationDay() == null ? LocalDate.MIN : listing.getCertificationDay();
LocalDate funcTestedEndDay = functionalityTested.getEndDay() == null ? LocalDate.MAX : functionalityTested.getEndDay();
return funcTestedEndDay.isBefore(listingStartDay);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public StandardAsOfCertificationDayReviewer(CertificationResultRules certResultR
}

public LocalDate getStandardsCheckDate(CertifiedProductSearchDetails listing) {
return listing.getCertificationDay();
return listing.getCertificationDay() == null ? LocalDate.MIN : listing.getCertificationDay();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ private void reviewTestToolAvailabilityAfterListingActiveDates(CertifiedProductS
}

private boolean isTestToolRetiredBeforeListingActiveDates(CertifiedProductSearchDetails listing, TestTool testTool) {
LocalDate listingStartDay = listing.getCertificationDay();
LocalDate listingStartDay = listing.getCertificationDay() == null ? LocalDate.MIN : listing.getCertificationDay();
LocalDate testToolEndDay = testTool.getEndDay() == null ? LocalDate.MAX : testTool.getEndDay();
return testToolEndDay.isBefore(listingStartDay);
}
Expand Down
Loading