diff --git a/lib/taskana-core/src/main/java/pro/taskana/Workbasket.java b/lib/taskana-core/src/main/java/pro/taskana/Workbasket.java index 4aaf39e10..b57e0f5c8 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/Workbasket.java +++ b/lib/taskana-core/src/main/java/pro/taskana/Workbasket.java @@ -1,7 +1,6 @@ package pro.taskana; import java.time.Instant; -import java.util.List; import pro.taskana.model.WorkbasketType; @@ -121,21 +120,6 @@ public interface Workbasket { */ String getOwner(); - /** - * Returns a list of all distribution targets. - * - * @return distributionTargets - */ - List getDistributionTargets(); - - /** - * Sets the list of distribution targets for this workbasket. - * - * @param distributionTargets - * the distribution targets of the workbasket - */ - void setDistributionTargets(List distributionTargets); - /** * Return the value for the custom1 attribute. * @@ -262,4 +246,5 @@ public interface Workbasket { * @return the WorkbasketSummary object for the current work basket */ WorkbasketSummary asSummary(); + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketQuery.java b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketQuery.java index 66461a1e6..f51693855 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketQuery.java +++ b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketQuery.java @@ -30,7 +30,7 @@ public interface WorkbasketQuery extends BaseQuery { * the keys as Strings * @return the query */ - BaseQuery keyLike(String... key); + WorkbasketQuery keyLike(String... key); /** * Add your names to your query. The names are compared case-insensitively to the names of workbaskets @@ -51,7 +51,7 @@ public interface WorkbasketQuery extends BaseQuery { * the names as Strings * @return the query */ - BaseQuery nameLike(String... name); + WorkbasketQuery nameLike(String... name); /** * Add search strings to your query that are searched case-insensitively in the key and name fields of workbaskets. @@ -63,7 +63,7 @@ public interface WorkbasketQuery extends BaseQuery { * the seach strings * @return the query */ - BaseQuery keyOrNameLike(String... searchString); + WorkbasketQuery keyOrNameLike(String... searchString); /** * Add your domains to your query. diff --git a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java index 271f939a7..0516080c6 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java +++ b/lib/taskana-core/src/main/java/pro/taskana/WorkbasketService.java @@ -121,7 +121,7 @@ public interface WorkbasketService { * @param authorization * the needed Authorization * @throws NotAuthorizedException - * if the current user has not the requested authorization fot the specified workbasket + * if the current user has not the requested authorization for the specified workbasket */ void checkAuthorization(String workbasketKey, WorkbasketAuthorization authorization) throws NotAuthorizedException; @@ -171,9 +171,68 @@ public interface WorkbasketService { * Returns a set with all permissions of the current user at this workbasket. * * @param workbasketKey - * The key of the referenced workbasket + * the key of the referenced workbasket * @return a Set with all permissions */ List getPermissionsForWorkbasket(String workbasketKey); + /** + * Returns the distribution targets for a given workbasket. + * + * @param workbasketId + * the id of the workbasket for which the distribution targets are to be retrieved + * @return the distribution targets of the specified workbasket + * @throws NotAuthorizedException + * if the current user has no read permission for the specified workbasket + * @throws WorkbasketNotFoundException + * if the workbasket doesn't exist + */ + List getDistributionTargets(String workbasketId) + throws NotAuthorizedException, WorkbasketNotFoundException; + + /** + * Set the distribution targets for a workbasket. + * + * @param sourceWorkbasketId + * the id of the source workbasket for which the distribution targets are to be set + * @param targetWorkbasketIds + * a list of the ids of the target workbaskets + * @throws NotAuthorizedException + * if the current used doesn't have READ permission for the source workbasket + * @throws WorkbasketNotFoundException + * if either the source workbasket or any of the target workbaskets don't exist + */ + void setDistributionTargets(String sourceWorkbasketId, List targetWorkbasketIds) + throws NotAuthorizedException, WorkbasketNotFoundException; + + /** + * Add a distribution target to a workbasket. If the specified distribution target exists already, the method + * silently returns without doing anything. + * + * @param sourceWorkbasketId + * the id of the source workbasket + * @param targetWorkbasketId + * the id of the target workbasket + * @throws NotAuthorizedException + * if the current user doesn't have READ permission for the source workbasket + * @throws WorkbasketNotFoundException + * if either the source workbasket or the target workbasket doesn't exist + */ + void addDistributionTarget(String sourceWorkbasketId, String targetWorkbasketId) + throws NotAuthorizedException, WorkbasketNotFoundException; + + /** + * Remove a distribution target from a workbasket. If the the specified distribution target doesn't exist, the + * method silently returns without doing anything. + * + * @param sourceWorkbasketId + * The id of the source workbasket + * @param targetWorkbasketId + * The id of the target workbasket + * @throws NotAuthorizedException + * If the current user doesn't have READ permission for the source workbasket + */ + void removeDistributionTarget(String sourceWorkbasketId, String targetWorkbasketId) + throws NotAuthorizedException; + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java index 8245e9505..61fda7ae0 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/TaskServiceImpl.java @@ -518,7 +518,7 @@ public class TaskServiceImpl implements TaskService { for (TaskSummaryImpl task : taskSummaries) { String workbasketKey = task.getWorkbasketSummaryImpl().getKey(); - // find the appropriate classification from the query result + // find the appropriate workbasket from the query result WorkbasketSummary aWorkbasket = workbaskets.stream() .filter(x -> workbasketKey != null && workbasketKey.equals(x.getKey())) .findFirst() diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketImpl.java index 25793d496..407019040 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketImpl.java @@ -1,8 +1,6 @@ package pro.taskana.impl; import java.time.Instant; -import java.util.ArrayList; -import java.util.List; import pro.taskana.Workbasket; import pro.taskana.WorkbasketSummary; @@ -22,7 +20,6 @@ public class WorkbasketImpl implements Workbasket { private String owner; private String domain; private WorkbasketType type; - private List distributionTargets = new ArrayList<>(); private String custom1; private String custom2; private String custom3; @@ -122,16 +119,6 @@ public class WorkbasketImpl implements Workbasket { this.type = type; } - @Override - public List getDistributionTargets() { - return distributionTargets; - } - - @Override - public void setDistributionTargets(List distributionTargets) { - this.distributionTargets = distributionTargets; - } - @Override public String getCustom1() { return custom1; @@ -229,6 +216,60 @@ public class WorkbasketImpl implements Workbasket { return result; } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((domain == null) ? 0 : domain.hashCode()); + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof WorkbasketImpl)) { + return false; + } + WorkbasketImpl other = (WorkbasketImpl) obj; + if (domain == null) { + if (other.domain != null) { + return false; + } + } else if (!domain.equals(other.domain)) { + return false; + } + if (id == null) { + if (other.id != null) { + return false; + } + } else if (!id.equals(other.id)) { + return false; + } + if (key == null) { + if (other.key != null) { + return false; + } + } else if (!key.equals(other.key)) { + return false; + } + if (name == null) { + if (other.name != null) { + return false; + } + } else if (!name.equals(other.name)) { + return false; + } + return true; + } + @Override public String toString() { StringBuilder builder = new StringBuilder(); @@ -250,8 +291,6 @@ public class WorkbasketImpl implements Workbasket { builder.append(domain); builder.append(", type="); builder.append(type); - builder.append(", distributionTargets="); - builder.append(distributionTargets); builder.append(", custom1="); builder.append(custom1); builder.append(", custom2="); diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketQueryImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketQueryImpl.java index fba60bfb9..4ff94d302 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketQueryImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketQueryImpl.java @@ -8,7 +8,6 @@ import org.apache.ibatis.session.RowBounds; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import pro.taskana.BaseQuery; import pro.taskana.TaskanaEngine; import pro.taskana.WorkbasketQuery; import pro.taskana.WorkbasketSummary; @@ -75,19 +74,19 @@ public class WorkbasketQueryImpl implements WorkbasketQuery { } @Override - public BaseQuery nameLike(String... names) { + public WorkbasketQuery nameLike(String... names) { this.nameLike = toUpperCopy(names); return this; } @Override - public BaseQuery keyLike(String... keys) { + public WorkbasketQuery keyLike(String... keys) { this.keyLike = toUpperCopy(keys); return this; } @Override - public BaseQuery keyOrNameLike(String... keysOrNames) { + public WorkbasketQuery keyOrNameLike(String... keysOrNames) { this.keyOrNameLike = toUpperCopy(keysOrNames); return this; } diff --git a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java index d3bac9c3d..8a0a3f4e9 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java +++ b/lib/taskana-core/src/main/java/pro/taskana/impl/WorkbasketServiceImpl.java @@ -16,6 +16,7 @@ import pro.taskana.WorkbasketService; import pro.taskana.WorkbasketSummary; import pro.taskana.exceptions.InvalidWorkbasketException; import pro.taskana.exceptions.NotAuthorizedException; +import pro.taskana.exceptions.SystemException; import pro.taskana.exceptions.WorkbasketNotFoundException; import pro.taskana.impl.util.IdGenerator; import pro.taskana.impl.util.LoggerUtils; @@ -34,8 +35,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { private static final Logger LOGGER = LoggerFactory.getLogger(WorkbasketServiceImpl.class); private static final String ID_PREFIX_WORKBASKET = "WBI"; private static final String ID_PREFIX_WORKBASKET_AUTHORIZATION = "WAI"; - private TaskanaEngine taskanaEngine; - private TaskanaEngineImpl taskanaEngineImpl; + private TaskanaEngineImpl taskanaEngine; private WorkbasketMapper workbasketMapper; private DistributionTargetMapper distributionTargetMapper; private WorkbasketAccessMapper workbasketAccessMapper; @@ -45,8 +45,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { public WorkbasketServiceImpl(TaskanaEngine taskanaEngine, WorkbasketMapper workbasketMapper, DistributionTargetMapper distributionTargetMapper, WorkbasketAccessMapper workbasketAccessMapper) { - this.taskanaEngine = taskanaEngine; - this.taskanaEngineImpl = (TaskanaEngineImpl) taskanaEngine; + this.taskanaEngine = (TaskanaEngineImpl) taskanaEngine; this.workbasketMapper = workbasketMapper; this.distributionTargetMapper = distributionTargetMapper; this.workbasketAccessMapper = workbasketAccessMapper; @@ -58,7 +57,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getWorkbasket(workbasketId = {})", workbasketId); Workbasket result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); result = workbasketMapper.findById(workbasketId); if (result == null) { LOGGER.error( @@ -69,7 +68,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { this.checkAuthorization(result.getKey(), WorkbasketAuthorization.READ); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from getWorkbasket(workbasketId). Returning result {} ", result); } } @@ -80,7 +79,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getWorkbasketByKey(workbasketKey = {})", workbasketKey); Workbasket result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); result = workbasketMapper.findByKey(workbasketKey); if (result == null) { LOGGER.error( @@ -91,7 +90,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { this.checkAuthorization(workbasketKey, WorkbasketAuthorization.READ); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from getWorkbasket(workbasketId). Returning result {} ", result); } } @@ -103,7 +102,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { } List result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); // use a set to avoid duplicates Set workbaskets = new HashSet<>(); for (String accessId : CurrentUserContext.getAccessIds()) { @@ -113,7 +112,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { result.addAll(workbaskets); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); if (LOGGER.isDebugEnabled()) { int numberOfResultObjects = result == null ? 0 : result.size(); LOGGER.debug("exit from getWorkbaskets(permissions). Returning {} resulting Objects: {} ", @@ -127,14 +126,14 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getWorkbaskets()"); List workbaskets = new ArrayList<>(); try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); List workbasketImpls = workbasketMapper.findAll(); for (WorkbasketSummaryImpl workbasketSummaryImpl : workbasketImpls) { workbaskets.add(workbasketSummaryImpl); } return workbaskets; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); if (LOGGER.isDebugEnabled()) { int numberOfResultObjects = workbaskets == null ? 0 : workbaskets.size(); LOGGER.debug("exit from getWorkbaskets(). Returning {} resulting Objects: {} ", numberOfResultObjects, @@ -150,7 +149,7 @@ public class WorkbasketServiceImpl implements WorkbasketService { Workbasket result = null; WorkbasketImpl workbasket = (WorkbasketImpl) newWorkbasket; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); Instant now = Instant.now(); workbasket.setCreated(now); workbasket.setModified(now); @@ -161,19 +160,10 @@ public class WorkbasketServiceImpl implements WorkbasketService { workbasketMapper.insert(workbasket); LOGGER.debug("Method createWorkbasket() created Workbasket '{}'", workbasket); - if (workbasket.getDistributionTargets() != null) { - for (WorkbasketSummary distributionTarget : workbasket.getDistributionTargets()) { - // validate that all distribution targets exist - this.getWorkbasket(distributionTarget.getId()); - distributionTargetMapper.insert(workbasket.getId(), distributionTarget.getId()); - LOGGER.debug("Method createWorkbasket() created distributiontarget for source '{}' and target {}", - workbasket.getId(), distributionTarget.getId()); - } - } result = workbasketMapper.findById(workbasket.getId()); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from createWorkbasket(workbasket). Returning result {} ", result); } } @@ -186,33 +176,14 @@ public class WorkbasketServiceImpl implements WorkbasketService { Workbasket result = null; WorkbasketImpl workbasket = (WorkbasketImpl) workbasketToUpdate; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); workbasket.setModified(Instant.now()); workbasketMapper.update(workbasket); LOGGER.debug("Method updateWorkbasket() updated workbasket '{}'", workbasket.getId()); - List oldDistributionTargets = distributionTargetMapper.findBySourceId(workbasket.getId()); - List newDistributionTargets = workbasket.getDistributionTargets(); - for (WorkbasketSummary distributionTarget : newDistributionTargets) { - if (!oldDistributionTargets.contains(distributionTarget.getId())) { - // check that old distribution target exists - getWorkbasket(distributionTarget.getId()); - distributionTargetMapper.insert(workbasket.getId(), distributionTarget.getId()); - LOGGER.debug("Method updateWorkbasket() created distributionTarget for '{}' and '{}'", - workbasket.getId(), distributionTarget.getId()); - } else { - oldDistributionTargets.remove(distributionTarget.getId()); - } - } - distributionTargetMapper.deleteMultiple(workbasket.getId(), oldDistributionTargets); - if (LOGGER.isInfoEnabled()) { - LOGGER.debug( - "Method updateWorkbasket() deleted distributionTargets for '{}' and old distribution targets {}", - workbasket.getId(), LoggerUtils.listToString(oldDistributionTargets)); - } result = workbasketMapper.findById(workbasket.getId()); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from updateWorkbasket(). Returning result {} ", result); } } @@ -221,14 +192,14 @@ public class WorkbasketServiceImpl implements WorkbasketService { public WorkbasketAccessItem createWorkbasketAuthorization(WorkbasketAccessItem workbasketAccessItem) { LOGGER.debug("entry to createWorkbasketAuthorization(workbasketAccessItem = {})", workbasketAccessItem); try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); workbasketAccessItem.setId(IdGenerator.generateWithPrefix(ID_PREFIX_WORKBASKET_AUTHORIZATION)); workbasketAccessMapper.insert(workbasketAccessItem); LOGGER.debug("Method createWorkbasketAuthorization() created workbaskteAccessItem {}", workbasketAccessItem); return workbasketAccessItem; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from createWorkbasketAuthorization(workbasketAccessItem). Returning result {}", workbasketAccessItem); } @@ -239,11 +210,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getWorkbasketAuthorization(id = {})", id); WorkbasketAccessItem result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); result = workbasketAccessMapper.findById(id); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from getWorkbasketAuthorization(id). Returning result {}", result); } } @@ -252,11 +223,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { public void deleteWorkbasketAuthorization(String id) { LOGGER.debug("entry to deleteWorkbasketAuthorization(id = {})", id); try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); workbasketAccessMapper.delete(id); LOGGER.debug("Method deleteWorkbasketAuthorization() deleted workbasketAccessItem wit Id {}", id); } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from deleteWorkbasketAuthorization(id)."); } } @@ -266,11 +237,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getAllAuthorizations()"); List result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); result = workbasketAccessMapper.findAll(); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); if (LOGGER.isDebugEnabled()) { int numberOfResultObjects = result == null ? 0 : result.size(); LOGGER.debug("exit from getAllAuthorizations(). Returning {} resulting Objects: {} ", @@ -282,49 +253,21 @@ public class WorkbasketServiceImpl implements WorkbasketService { @Override public void checkAuthorization(String workbasketKey, WorkbasketAuthorization workbasketAuthorization) throws NotAuthorizedException { - LOGGER.debug("entry to checkAuthorization(workbasketId = {}, workbasketAuthorization = {})", workbasketKey, - workbasketAuthorization); - boolean isAuthorized = false; - try { - taskanaEngineImpl.openConnection(); - // Skip permission check is security is not enabled - if (!taskanaEngine.getConfiguration().isSecurityEnabled()) { - LOGGER.debug("Skipping permissions check since security is disabled."); - isAuthorized = true; - return; - } - List accessIds = CurrentUserContext.getAccessIds(); - LOGGER.debug("checkAuthorization: Verifying that {} has the permission {} on workbasket {}", - CurrentUserContext.getUserid(), workbasketAuthorization.name(), workbasketKey); - - List accessItems = workbasketAccessMapper - .findByWorkbasketAndAccessIdAndAuthorization(workbasketKey, accessIds, workbasketAuthorization.name()); - - if (accessItems.size() <= 0) { - throw new NotAuthorizedException("Not authorized. Authorization '" + workbasketAuthorization.name() - + "' on workbasket '" + workbasketKey + "' is needed."); - } - - isAuthorized = true; - - } finally { - taskanaEngineImpl.returnConnection(); - LOGGER.debug("exit from checkAuthorization(). User is authorized = {}.", isAuthorized); - } + checkAuthorization(workbasketKey, null, workbasketAuthorization); } @Override public WorkbasketAccessItem updateWorkbasketAuthorization(WorkbasketAccessItem workbasketAccessItem) { LOGGER.debug("entry to updateWorkbasketAuthorization(workbasketAccessItem = {}", workbasketAccessItem); try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); workbasketAccessMapper.update(workbasketAccessItem); LOGGER.debug("Method updateWorkbasketAuthorization() updated workbasketAccessItem {}", workbasketAccessItem); return workbasketAccessItem; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); LOGGER.debug("exit from updateWorkbasketAuthorization(workbasketAccessItem). Returning {}", workbasketAccessItem); } @@ -335,11 +278,11 @@ public class WorkbasketServiceImpl implements WorkbasketService { LOGGER.debug("entry to getWorkbasketAuthorizations(workbasketId = {})", workbasketKey); List result = null; try { - taskanaEngineImpl.openConnection(); + taskanaEngine.openConnection(); result = workbasketAccessMapper.findByWorkbasketKey(workbasketKey); return result; } finally { - taskanaEngineImpl.returnConnection(); + taskanaEngine.returnConnection(); if (LOGGER.isDebugEnabled()) { int numberOfResultObjects = result == null ? 0 : result.size(); LOGGER.debug("exit from getWorkbasketAuthorizations(workbasketId). Returning {} resulting Objects: {} ", @@ -351,7 +294,8 @@ public class WorkbasketServiceImpl implements WorkbasketService { @Override public List getPermissionsForWorkbasket(String workbasketKey) { List permissions = new ArrayList<>(); - WorkbasketAccessItem wbAcc = workbasketAccessMapper.findByWorkbasketAndAccessId(workbasketKey, CurrentUserContext.getAccessIds()); + WorkbasketAccessItem wbAcc = workbasketAccessMapper.findByWorkbasketAndAccessId(workbasketKey, + CurrentUserContext.getAccessIds()); this.addWorkbasketAccessItemValuesToPermissionSet(wbAcc, permissions); return permissions; } @@ -379,7 +323,8 @@ public class WorkbasketServiceImpl implements WorkbasketService { } } - private void addWorkbasketAccessItemValuesToPermissionSet(WorkbasketAccessItem workbasketAccessItem, List permissions) { + private void addWorkbasketAccessItemValuesToPermissionSet(WorkbasketAccessItem workbasketAccessItem, + List permissions) { if (workbasketAccessItem.isPermOpen()) { permissions.add(WorkbasketAuthorization.OPEN); } @@ -425,4 +370,190 @@ public class WorkbasketServiceImpl implements WorkbasketService { public Workbasket newWorkbasket() { return new WorkbasketImpl(); } + + @Override + public List getDistributionTargets(String workbasketId) + throws NotAuthorizedException, WorkbasketNotFoundException { + LOGGER.debug("entry to getDistributionTargets(workbasketId = {})", workbasketId); + List result = new ArrayList<>(); + try { + taskanaEngine.openConnection(); + // check that source workbasket exists + getWorkbasket(workbasketId); + checkAuthorizationByWorkbasketId(workbasketId, WorkbasketAuthorization.READ); + List distributionTargets = workbasketMapper + .findByDistributionTargets(workbasketId); + result.addAll(distributionTargets); + return result; + } finally { + taskanaEngine.returnConnection(); + if (LOGGER.isDebugEnabled()) { + int numberOfResultObjects = result == null ? 0 : result.size(); + LOGGER.debug("exit from getDistributionTargets(workbasketId). Returning {} resulting Objects: {} ", + numberOfResultObjects, LoggerUtils.listToString(result)); + } + } + } + + @Override + public void setDistributionTargets(String sourceWorkbasketId, List targetWorkbasketIds) + throws WorkbasketNotFoundException, NotAuthorizedException { + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("entry to setDistributionTargets(sourceWorkbasketId = {}, targetWorkazketIds = {})", + sourceWorkbasketId, + LoggerUtils.listToString(targetWorkbasketIds)); + } + try { + taskanaEngine.openConnection(); + // check existence of source workbasket + WorkbasketImpl sourceWorkbasket = (WorkbasketImpl) getWorkbasket(sourceWorkbasketId); + checkAuthorizationByWorkbasketId(sourceWorkbasketId, WorkbasketAuthorization.READ); + distributionTargetMapper.deleteAllDistributionTargets(sourceWorkbasketId); + + sourceWorkbasket.setModified(Instant.now()); + workbasketMapper.update(sourceWorkbasket); + + if (targetWorkbasketIds != null) { + for (String targetId : targetWorkbasketIds) { + // check for existence of target workbasket + getWorkbasket(targetId); + distributionTargetMapper.insert(sourceWorkbasketId, targetId); + LOGGER.debug( + "Method setDistributionTargets() created distributiontarget for source '{}' and target {}", + sourceWorkbasketId, targetId); + } + } + } finally { + taskanaEngine.returnConnection(); + if (LOGGER.isDebugEnabled()) { + LOGGER.debug("setDistributionTargets set {} distribution targets to source workbasket {} ", + targetWorkbasketIds.size(), sourceWorkbasketId); + } + } + + } + + @Override + public void addDistributionTarget(String sourceWorkbasketId, String targetWorkbasketId) + throws NotAuthorizedException, WorkbasketNotFoundException { + LOGGER.debug("entry to addDistributionTarget(sourceWorkbasketId = {}, targetWorkbasketId = {})", + sourceWorkbasketId, targetWorkbasketId); + try { + taskanaEngine.openConnection(); + // check existence of source workbasket + WorkbasketImpl sourceWorkbasket = (WorkbasketImpl) getWorkbasket(sourceWorkbasketId); + // check esistence of target workbasket + getWorkbasket(targetWorkbasketId); + checkAuthorizationByWorkbasketId(sourceWorkbasketId, WorkbasketAuthorization.READ); + // check whether the target is already set as target + int numOfDistTargets = distributionTargetMapper.getNumberOfDistributionTargets(sourceWorkbasketId, + targetWorkbasketId); + if (numOfDistTargets > 0) { + LOGGER.debug( + "addDistributionTarget detected that the specified distribution target exists already. Doing nothing..."); + } else { + distributionTargetMapper.insert(sourceWorkbasketId, targetWorkbasketId); + LOGGER.debug("addDistributionTarget inserted distribution target sourceId = {}, targetId = {}", + sourceWorkbasketId, targetWorkbasketId); + sourceWorkbasket.setModified(Instant.now()); + workbasketMapper.update(sourceWorkbasket); + } + + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from addDistributionTarget"); + } + + } + + @Override + public void removeDistributionTarget(String sourceWorkbasketId, String targetWorkbasketId) + throws NotAuthorizedException { + LOGGER.debug("entry to removeDistributionTarget(sourceWorkbasketId = {}, targetWorkbasketId = {})", + sourceWorkbasketId, targetWorkbasketId); + try { + taskanaEngine.openConnection(); + // don't check existence of source / target workbasket to enable cleanup even if the db is corrupted + checkAuthorizationByWorkbasketId(sourceWorkbasketId, WorkbasketAuthorization.READ); + // check whether the target is set as target + int numberOfDistTargets = distributionTargetMapper.getNumberOfDistributionTargets(sourceWorkbasketId, + targetWorkbasketId); + if (numberOfDistTargets > 0) { + distributionTargetMapper.delete(sourceWorkbasketId, targetWorkbasketId); + LOGGER.debug("removeDistributionTarget deleted distribution target sourceId = {}, targetId = {}", + sourceWorkbasketId, targetWorkbasketId); + + try { + WorkbasketImpl sourceWorkbasket = (WorkbasketImpl) getWorkbasket(sourceWorkbasketId); + sourceWorkbasket.setModified(Instant.now()); + workbasketMapper.update(sourceWorkbasket); + } catch (WorkbasketNotFoundException e) { + LOGGER.debug( + "removeDistributionTarget found that the source workbasket {} doesn't exist. Ignoring the request... ", + sourceWorkbasketId); + } + + } else { + LOGGER.debug( + "removeDistributionTarget detected that the specified distribution target doesn't exist. Doing nothing..."); + } + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from addDistributionTarget"); + } + + } + + private void checkAuthorizationByWorkbasketId(String workbasketId, + WorkbasketAuthorization workbasketAuthorization) throws NotAuthorizedException { + checkAuthorization(null, workbasketId, workbasketAuthorization); + } + + private void checkAuthorization(String workbasketKey, String workbasketId, + WorkbasketAuthorization workbasketAuthorization) + throws NotAuthorizedException { + LOGGER.debug("entry to checkAuthorization(workbasketId = {}, workbasketAuthorization = {})", workbasketKey, + workbasketAuthorization); + boolean isAuthorized = false; + try { + taskanaEngine.openConnection(); + // Skip permission check is security is not enabled + if (!taskanaEngine.getConfiguration().isSecurityEnabled()) { + LOGGER.debug("Skipping permissions check since security is disabled."); + isAuthorized = true; + return; + } + + List accessIds = CurrentUserContext.getAccessIds(); + LOGGER.debug("checkAuthorization: Verifying that {} has the permission {} on workbasket {}", + CurrentUserContext.getUserid(), workbasketAuthorization.name(), workbasketKey); + + List accessItems; + + if (workbasketKey != null) { + accessItems = workbasketAccessMapper + .findByWorkbasketAndAccessIdAndAuthorization(workbasketKey, accessIds, + workbasketAuthorization.name()); + } else if (workbasketId != null) { + accessItems = workbasketAccessMapper + .findByWorkbasketAndAccessIdAndAuthorizationsById(workbasketId, accessIds, + workbasketAuthorization.name()); + } else { + throw new SystemException( + "checkAuthorizationImpl was called with both workbasketKey and workbasketId set to null"); + } + + if (accessItems.size() <= 0) { + throw new NotAuthorizedException("Not authorized. Authorization '" + workbasketAuthorization.name() + + "' on workbasket '" + workbasketKey + "' is needed."); + } + + isAuthorized = true; + + } finally { + taskanaEngine.returnConnection(); + LOGGER.debug("exit from checkAuthorization(). User is authorized = {}.", isAuthorized); + } + } + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/DistributionTargetMapper.java b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/DistributionTargetMapper.java index 2fedf6f1b..1208bf816 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/DistributionTargetMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/DistributionTargetMapper.java @@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; + /** * This class is the mybatis mapping of distribution targets. */ @@ -20,6 +21,12 @@ public interface DistributionTargetMapper { @Select("SELECT TARGET_ID FROM DISTRIBUTION_TARGETS WHERE SOURCE_ID = #{sourceId}") List findBySourceId(@Param("sourceId") String sourceId); + @Select("SELECT count(*) FROM DISTRIBUTION_TARGETS WHERE SOURCE_ID = #{sourceId} AND TARGET_ID = #{targetId}") + int getNumberOfDistributionTargets(@Param("sourceId") String sourceId, @Param("targetId") String targetId); + @Delete("") void deleteMultiple(@Param("sourceId") String sourceId, @Param("targetId") List targetId); + + @Delete("DELETE FROM DISTRIBUTION_TARGETS WHERE SOURCE_ID = #{sourceId}") + void deleteAllDistributionTargets(@Param("sourceId") String sourceId); } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketAccessMapper.java b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketAccessMapper.java index 0a36635ba..c97e29623 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketAccessMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketAccessMapper.java @@ -169,4 +169,43 @@ public interface WorkbasketAccessMapper { List findByWorkbasketAndAccessIdAndAuthorization( @Param("workbasketKey") String workbasketKey, @Param("accessIds") List accessIds, @Param("authorization") String authorization); + @Select("") + @Results(value = { + @Result(property = "id", column = "ID"), + @Result(property = "workbasketKey", column = "WORKBASKET_KEY"), + @Result(property = "accessId", column = "ACCESS_ID"), + @Result(property = "permRead", column = "PERM_READ"), + @Result(property = "permOpen", column = "PERM_OPEN"), + @Result(property = "permAppend", column = "PERM_APPEND"), + @Result(property = "permTransfer", column = "PERM_TRANSFER"), + @Result(property = "permDistribute", column = "PERM_DISTRIBUTE"), + @Result(property = "permCustom1", column = "PERM_CUSTOM_1"), + @Result(property = "permCustom2", column = "PERM_CUSTOM_2"), + @Result(property = "permCustom3", column = "PERM_CUSTOM_3"), + @Result(property = "permCustom4", column = "PERM_CUSTOM_4"), + @Result(property = "permCustom5", column = "PERM_CUSTOM_5"), + @Result(property = "permCustom6", column = "PERM_CUSTOM_6"), + @Result(property = "permCustom7", column = "PERM_CUSTOM_7"), + @Result(property = "permCustom8", column = "PERM_CUSTOM_8")}) + List findByWorkbasketAndAccessIdAndAuthorizationsById( + @Param("workbasketId") String workbasketId, @Param("accessIds") List accessIds, + @Param("authorization") String authorization); + } diff --git a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketMapper.java b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketMapper.java index 60961d0d1..48aa8e556 100644 --- a/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketMapper.java +++ b/lib/taskana-core/src/main/java/pro/taskana/model/mappings/WorkbasketMapper.java @@ -4,14 +4,12 @@ import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.Many; import org.apache.ibatis.annotations.Options; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; -import org.apache.ibatis.mapping.FetchType; import pro.taskana.impl.WorkbasketImpl; import pro.taskana.impl.WorkbasketSummaryImpl; @@ -32,8 +30,6 @@ public interface WorkbasketMapper { @Result(property = "type", column = "TYPE"), @Result(property = "description", column = "DESCRIPTION"), @Result(property = "owner", column = "OWNER"), - @Result(property = "distributionTargets", column = "ID", javaType = List.class, - many = @Many(fetchType = FetchType.DEFAULT, select = "findByDistributionTargets")), @Result(property = "custom1", column = "CUSTOM_1"), @Result(property = "custom2", column = "CUSTOM_2"), @Result(property = "custom3", column = "CUSTOM_3"), @@ -41,7 +37,7 @@ public interface WorkbasketMapper { @Result(property = "orgLevel1", column = "ORG_LEVEL_1"), @Result(property = "orgLevel2", column = "ORG_LEVEL_2"), @Result(property = "orgLevel3", column = "ORG_LEVEL_3"), - @Result(property = "orgLevel4", column = "ORG_LEVEL_4") }) + @Result(property = "orgLevel4", column = "ORG_LEVEL_4")}) WorkbasketImpl findById(@Param("id") String id); @Select("SELECT ID, KEY, CREATED, MODIFIED, NAME, DOMAIN, TYPE, DESCRIPTION, OWNER, CUSTOM_1 ,CUSTOM_2 ,CUSTOM_3 ,CUSTOM_4 ,ORG_LEVEL_1 ,ORG_LEVEL_2 ,ORG_LEVEL_3 ,ORG_LEVEL_4 FROM WORKBASKET WHERE KEY = #{key}") @@ -54,8 +50,6 @@ public interface WorkbasketMapper { @Result(property = "type", column = "TYPE"), @Result(property = "description", column = "DESCRIPTION"), @Result(property = "owner", column = "OWNER"), - @Result(property = "distributionTargets", column = "ID", javaType = List.class, - many = @Many(fetchType = FetchType.DEFAULT, select = "findByDistributionTargets")), @Result(property = "custom1", column = "CUSTOM_1"), @Result(property = "custom2", column = "CUSTOM_2"), @Result(property = "custom3", column = "CUSTOM_3"), @@ -64,7 +58,7 @@ public interface WorkbasketMapper { @Result(property = "orgLevel1", column = "ORG_LEVEL_1"), @Result(property = "orgLevel2", column = "ORG_LEVEL_2"), @Result(property = "orgLevel3", column = "ORG_LEVEL_3"), - @Result(property = "orgLevel4", column = "ORG_LEVEL_4") }) + @Result(property = "orgLevel4", column = "ORG_LEVEL_4")}) WorkbasketImpl findByKey(@Param("key") String key); @Select("SELECT * FROM WORKBASKET WHERE id IN (SELECT TARGET_ID FROM DISTRIBUTION_TARGETS WHERE SOURCE_ID = #{id})") @@ -80,7 +74,7 @@ public interface WorkbasketMapper { @Result(property = "orgLevel1", column = "ORG_LEVEL_1"), @Result(property = "orgLevel2", column = "ORG_LEVEL_2"), @Result(property = "orgLevel3", column = "ORG_LEVEL_3"), - @Result(property = "orgLevel4", column = "ORG_LEVEL_4") }) + @Result(property = "orgLevel4", column = "ORG_LEVEL_4")}) List findByDistributionTargets(@Param("id") String id); @Select("SELECT ID, KEY, NAME, DESCRIPTION, OWNER, DOMAIN, TYPE, ORG_LEVEL_1, ORG_LEVEL_2, ORG_LEVEL_3, ORG_LEVEL_4 FROM WORKBASKET WHERE key = #{key}") @@ -111,7 +105,7 @@ public interface WorkbasketMapper { @Result(property = "orgLevel1", column = "ORG_LEVEL_1"), @Result(property = "orgLevel2", column = "ORG_LEVEL_2"), @Result(property = "orgLevel3", column = "ORG_LEVEL_3"), - @Result(property = "orgLevel4", column = "ORG_LEVEL_4") }) + @Result(property = "orgLevel4", column = "ORG_LEVEL_4")}) List findAll(); @Select("