From 49592e41fdf2330be5c9920dd7ad3e2225e7ba39 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 15 Feb 2018 11:51:12 +0100 Subject: [PATCH] OO-3312: hide the lost+found in the document pool site, exclude competence gained from a taxonomy level with the identifier lost+found or orphan-fach (inclusive parent line) to access the document pool site --- .../modules/docpool/DocumentPoolManager.java | 4 +- .../manager/DocumentPoolManagerImpl.java | 16 +++-- .../docpool/site/DocumentPoolSite.java | 4 +- .../olat/modules/taxonomy/TaxonomyModule.java | 10 +++ .../taxonomy/manager/TaxonomyTreeBuilder.java | 39 +++++++++--- .../taxonomy/model/TaxonomyTreeNode.java | 6 +- .../manager/DocumentPoolManagerTest.java | 62 ++++++++++++++++--- 7 files changed, 111 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/olat/modules/docpool/DocumentPoolManager.java b/src/main/java/org/olat/modules/docpool/DocumentPoolManager.java index 2cd06ef7568..dc90d7002d8 100644 --- a/src/main/java/org/olat/modules/docpool/DocumentPoolManager.java +++ b/src/main/java/org/olat/modules/docpool/DocumentPoolManager.java @@ -30,7 +30,9 @@ import org.olat.basesecurity.IdentityRef; public interface DocumentPoolManager { /** - * Has a valid competence to see the document pool. + * Has a valid competence to see the document pool. The presence of a + * taxonomy level with the identifier "lost+found" or "orphan-fach" in the + * parent line of level exclude the competence. * * @param identity The identity which want to access the document pool * @return true/false diff --git a/src/main/java/org/olat/modules/docpool/manager/DocumentPoolManagerImpl.java b/src/main/java/org/olat/modules/docpool/manager/DocumentPoolManagerImpl.java index 6c6f681b589..b39a4325b02 100644 --- a/src/main/java/org/olat/modules/docpool/manager/DocumentPoolManagerImpl.java +++ b/src/main/java/org/olat/modules/docpool/manager/DocumentPoolManagerImpl.java @@ -29,6 +29,7 @@ import org.olat.core.util.StringHelper; import org.olat.modules.docpool.DocumentPoolManager; import org.olat.modules.docpool.DocumentPoolModule; import org.olat.modules.taxonomy.TaxonomyCompetenceTypes; +import org.olat.modules.taxonomy.TaxonomyModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -44,6 +45,8 @@ public class DocumentPoolManagerImpl implements DocumentPoolManager { @Autowired private DB dbInstance; @Autowired + private TaxonomyModule taxonomyModule; + @Autowired private DocumentPoolModule documentPoolModule; @Override @@ -56,9 +59,9 @@ public class DocumentPoolManagerImpl implements DocumentPoolManager { StringBuilder sb = new StringBuilder(256); sb.append("select competence.key from ctaxonomycompetence competence") .append(" inner join competence.identity ident") - .append(" inner join competence.taxonomyLevel taxonomyLevel") - .append(" inner join taxonomyLevel.type type") - .append(" where taxonomyLevel.taxonomy.key=:taxonomyKey and ident.key=:identityKey") + .append(" inner join competence.taxonomyLevel level") + .append(" inner join level.type type") + .append(" where level.taxonomy.key=:taxonomyKey and ident.key=:identityKey") .append(" and (") .append(" (competence.type='").append(TaxonomyCompetenceTypes.manage.name()).append("' and type.documentsLibraryManagerCompetenceEnabled=true)") .append(" or") @@ -67,13 +70,18 @@ public class DocumentPoolManagerImpl implements DocumentPoolManager { .append(" (competence.type='").append(TaxonomyCompetenceTypes.have.name()).append("' and type.documentsLibraryHaveCompetenceReadEnabled=true)") .append(" or") .append(" (competence.type='").append(TaxonomyCompetenceTypes.target.name()).append("' and type.documentsLibraryTargetCompetenceReadEnabled=true)") - .append(")"); + .append(" ) and not(level.identifier in (:lostFoundIds))") + .append(" and not exists (select parent.key from ctaxonomylevel parent") + .append(" where locate(parent.materializedPathKeys, level.materializedPathKeys) = 1") + .append(" and parent.identifier in (:lostFoundIds)") + .append(" )"); List<Long> competenceKeys = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), Long.class) .setFlushMode(FlushModeType.COMMIT)//don't flush for this query .setParameter("taxonomyKey", new Long(taxonomyKey)) .setParameter("identityKey", identity.getKey()) + .setParameter("lostFoundIds", taxonomyModule.getLostAndFoundsIdentifiers()) .setFirstResult(0) .setMaxResults(1) .getResultList(); diff --git a/src/main/java/org/olat/modules/docpool/site/DocumentPoolSite.java b/src/main/java/org/olat/modules/docpool/site/DocumentPoolSite.java index 776181fb77c..a4efe6e1a3b 100644 --- a/src/main/java/org/olat/modules/docpool/site/DocumentPoolSite.java +++ b/src/main/java/org/olat/modules/docpool/site/DocumentPoolSite.java @@ -70,13 +70,11 @@ public class DocumentPoolSite extends AbstractSiteInstance { OLATResourceable ores = OresHelper.createOLATResourceableInstance(DocumentPoolSite.class, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ureq, ores, new StateSite(this), wControl, true); - DocumentPoolMainController mainController = new DocumentPoolMainController(ureq, bwControl); - return mainController; + return new DocumentPoolMainController(ureq, bwControl); } @Override public void reset() { curNavElem = new DefaultNavElement(origNavElem); } - } diff --git a/src/main/java/org/olat/modules/taxonomy/TaxonomyModule.java b/src/main/java/org/olat/modules/taxonomy/TaxonomyModule.java index 22684a4b3dc..04f8b1aca41 100644 --- a/src/main/java/org/olat/modules/taxonomy/TaxonomyModule.java +++ b/src/main/java/org/olat/modules/taxonomy/TaxonomyModule.java @@ -19,6 +19,9 @@ */ package org.olat.modules.taxonomy; +import java.util.ArrayList; +import java.util.List; + import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.configuration.ConfigOnOff; import org.olat.core.util.StringHelper; @@ -72,4 +75,11 @@ public class TaxonomyModule extends AbstractSpringModule implements ConfigOnOff public boolean isManagedTaxonomyLevels() { return true; } + + public List<String> getLostAndFoundsIdentifiers() { + List<String> identifiers = new ArrayList<>(2); + identifiers.add("orphan-fach"); + identifiers.add("lost+found"); + return identifiers; + } } diff --git a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyTreeBuilder.java b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyTreeBuilder.java index 655d2b08e5b..b458740aa40 100644 --- a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyTreeBuilder.java +++ b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyTreeBuilder.java @@ -39,6 +39,7 @@ import org.olat.modules.taxonomy.TaxonomyCompetence; import org.olat.modules.taxonomy.TaxonomyCompetenceTypes; import org.olat.modules.taxonomy.TaxonomyLevel; import org.olat.modules.taxonomy.TaxonomyLevelType; +import org.olat.modules.taxonomy.TaxonomyModule; import org.olat.modules.taxonomy.TaxonomyService; import org.olat.modules.taxonomy.model.TaxonomyTreeNode; import org.olat.modules.taxonomy.model.TaxonomyTreeNodeType; @@ -63,10 +64,12 @@ public class TaxonomyTreeBuilder { private final boolean enableTemplates; private final TaxonomyService taxonomyService; + private final List<String> lostAndFoundIdentifiers; public TaxonomyTreeBuilder(Taxonomy taxonomy, Identity identity, String rootTitle, boolean isTaxonomyAdmin, boolean enableTemplates, String templateDirectory, Locale locale) { taxonomyService = CoreSpringFactory.getImpl(TaxonomyService.class); + lostAndFoundIdentifiers = CoreSpringFactory.getImpl(TaxonomyModule.class).getLostAndFoundsIdentifiers(); this.locale = locale; this.taxonomy = taxonomy; this.identity = identity; @@ -113,7 +116,7 @@ public class TaxonomyTreeBuilder { Long key = taxonomyLevel.getKey(); TaxonomyTreeNode node = fieldKeyToNode.get(key); if(node == null) { - node = new TaxonomyTreeNode(taxonomy, taxonomyLevel); + node = new TaxonomyTreeNode(taxonomy, taxonomyLevel, getType(taxonomyLevel)); TaxonomyLevelType type = taxonomyLevel.getType(); if(type != null && StringHelper.containsNonWhitespace(type.getCssClass())) { node.setIconCssClass(type.getCssClass()); @@ -130,7 +133,7 @@ public class TaxonomyTreeBuilder { TaxonomyTreeNode parentNode = fieldKeyToNode.get(parentKey); if(parentNode == null) { parentLevel = keytoLevels.get(parentKey);//to use the fetched type - parentNode = new TaxonomyTreeNode(taxonomy, parentLevel); + parentNode = new TaxonomyTreeNode(taxonomy, parentLevel, getType(parentLevel)); TaxonomyLevelType type = parentLevel.getType(); if(type != null && StringHelper.containsNonWhitespace(type.getCssClass())) { parentNode.setIconCssClass(type.getCssClass()); @@ -148,6 +151,21 @@ public class TaxonomyTreeBuilder { return gtm; } + private TaxonomyTreeNodeType getType(TaxonomyLevel taxonomyLevel) { + TaxonomyTreeNodeType type; + String identifier = taxonomyLevel.getIdentifier(); + if(StringHelper.containsNonWhitespace(identifier)) { + if(lostAndFoundIdentifiers.contains(identifier)) { + type = TaxonomyTreeNodeType.lostAndFound; + } else { + type = TaxonomyTreeNodeType.taxonomyLevel; + } + } else { + type = TaxonomyTreeNodeType.taxonomyLevel; + } + return type; + } + private void sort(TaxonomyTreeNode parent) { parent.sort(new TaxonomyTreeNodeComparator()); for(int i=parent.getChildCount(); i-->0; ) { @@ -160,9 +178,9 @@ public class TaxonomyTreeBuilder { do { someInvisible = false; List<TaxonomyTreeNode> children = listChildren(parent); - for(TaxonomyTreeNode child:children) { - if(!child.isVisible()) { + //remove invisible nodes and lost+found + if(!child.isVisible() || child.getType() == TaxonomyTreeNodeType.lostAndFound) { List<TaxonomyTreeNode> childrenOfChild = listChildren(child); parent.remove(child); for(TaxonomyTreeNode childOfChild : childrenOfChild) { @@ -206,7 +224,13 @@ public class TaxonomyTreeBuilder { private void computePermissionsRecursive(TaxonomyTreeNode node, Map<TaxonomyLevel, List<TaxonomyCompetenceTypes>> levelToCompetences) { boolean hasRead = node.isCanRead(); boolean hasWrite = node.isCanWrite(); - if(node.getTaxonomyLevel() != null) { + + if(node.getType() == TaxonomyTreeNodeType.lostAndFound) { + hasRead = isTaxonomyAdmin; + hasWrite = isTaxonomyAdmin; + node.setCanRead(hasRead); + node.setCanWrite(hasWrite); + } else if(node.getTaxonomyLevel() != null) { TaxonomyLevel level = node.getTaxonomyLevel(); TaxonomyLevelType type = level.getType(); if(type != null) { @@ -238,11 +262,6 @@ public class TaxonomyTreeBuilder { hasWrite = isTaxonomyAdmin; node.setCanRead(hasRead); node.setCanWrite(hasWrite); - } else if(node.getType() == TaxonomyTreeNodeType.lostAndFound) { - hasRead = isTaxonomyAdmin; - hasWrite = false; - node.setCanRead(hasRead); - node.setCanWrite(hasWrite); } for(int i=node.getChildCount(); i-->0; ) { diff --git a/src/main/java/org/olat/modules/taxonomy/model/TaxonomyTreeNode.java b/src/main/java/org/olat/modules/taxonomy/model/TaxonomyTreeNode.java index 3823c037ab7..12b0a77c45d 100644 --- a/src/main/java/org/olat/modules/taxonomy/model/TaxonomyTreeNode.java +++ b/src/main/java/org/olat/modules/taxonomy/model/TaxonomyTreeNode.java @@ -57,13 +57,13 @@ public class TaxonomyTreeNode extends GenericTreeNode { nodeType = type; } - public TaxonomyTreeNode(Taxonomy taxonomy, TaxonomyLevel taxonomyLevel) { + public TaxonomyTreeNode(Taxonomy taxonomy, TaxonomyLevel taxonomyLevel, TaxonomyTreeNodeType type) { super(taxonomyLevel.getKey().toString()); setTitle(taxonomyLevel.getDisplayName()); this.taxonomy = taxonomy; this.taxonomyLevel = taxonomyLevel; setUserObject(taxonomyLevel); - nodeType = TaxonomyTreeNodeType.taxonomyLevel; + nodeType = type; } public TaxonomyTreeNodeType getType() { @@ -72,7 +72,7 @@ public class TaxonomyTreeNode extends GenericTreeNode { public boolean isVisible() { return nodeType == TaxonomyTreeNodeType.taxonomy - || nodeType == TaxonomyTreeNodeType.templates + || nodeType == TaxonomyTreeNodeType.templates || (taxonomyLevel != null && (taxonomyLevel.getType() == null ? true : taxonomyLevel.getType().isVisible())); } diff --git a/src/test/java/org/olat/modules/docpool/manager/DocumentPoolManagerTest.java b/src/test/java/org/olat/modules/docpool/manager/DocumentPoolManagerTest.java index 0eda1be36e0..cba262187f7 100644 --- a/src/test/java/org/olat/modules/docpool/manager/DocumentPoolManagerTest.java +++ b/src/test/java/org/olat/modules/docpool/manager/DocumentPoolManagerTest.java @@ -84,7 +84,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_manage() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.manage); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.manage); // set read for teach competence type.setDocumentsLibraryManageCompetenceEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -98,7 +98,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_teachRead() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.teach); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.teach); // set read for teach competence type.setDocumentsLibraryTeachCompetenceReadEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -112,7 +112,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_teachWrite() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.teach); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.teach); // set read for teach competence type.setDocumentsLibraryTeachCompetenceWriteEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -126,7 +126,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_teach_negative() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.teach); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.teach); // set read for teach competence type.setDocumentsLibraryManageCompetenceEnabled(true); type.setDocumentsLibraryHaveCompetenceReadEnabled(true); @@ -142,7 +142,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_have() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.have); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.have); // set read for teach competence type.setDocumentsLibraryHaveCompetenceReadEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -156,7 +156,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_have_negative() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.have); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.have); // set read for teach competence type.setDocumentsLibraryTeachCompetenceReadEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -170,7 +170,7 @@ public class DocumentPoolManagerTest extends OlatTestCase { public void hasCompetenceByTaxonomy_target() { // create a level and competence with a type teach Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); - TaxonomyLevelType type = createTypeLevelCompetence(id, TaxonomyCompetenceTypes.target); + TaxonomyLevelType type = createTypeLevelCompetence(id, null, TaxonomyCompetenceTypes.target); // set read for teach competence type.setDocumentsLibraryTargetCompetenceReadEnabled(true); type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); @@ -193,11 +193,55 @@ public class DocumentPoolManagerTest extends OlatTestCase { Assert.assertFalse(hasCompetence); } - private TaxonomyLevelType createTypeLevelCompetence(Identity id, TaxonomyCompetenceTypes competenceType) { + /** + * The test check if the presence of a level with the identifier lost+found + * in the parent line stop the competence. + */ + @Test + public void lostAndFoundSpecialCase() { + Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("competent-8"); + Taxonomy taxonomy = getDocumentPoolTaxonomy(); + TaxonomyLevel level1 = taxonomyLevelDao.createTaxonomyLevel("DP-Lev. " + UUID.randomUUID(), "Competence level", "A competence", null, null, null, null, taxonomy); + TaxonomyLevel level2 = taxonomyLevelDao.createTaxonomyLevel("DP-Lev. " + UUID.randomUUID(), "Competence level", "A competence", null, null, level1, null, taxonomy); + TaxonomyLevelType type = createTypeLevelCompetence(id, level2, TaxonomyCompetenceTypes.have); + type.setDocumentsLibraryHaveCompetenceReadEnabled(true); + type = taxonomyLevelTypeDao.updateTaxonomyLevelType(type); + dbInstance.commitAndCloseSession(); + + //check first without lost+found + boolean hasCompetence = documentPoolManager.hasValidCompetence(id); + Assert.assertTrue(hasCompetence); + + //change the identifier level 2 + level2.setIdentifier("lost+found"); + level2 = taxonomyLevelDao.updateTaxonomyLevel(level2); + dbInstance.commitAndCloseSession(); + + //access refused + boolean hasLostCompetence = documentPoolManager.hasValidCompetence(id); + Assert.assertFalse(hasLostCompetence); + + // remove lost + found + level2.setIdentifier("DP-Lev. " + UUID.randomUUID()); + level2 = taxonomyLevelDao.updateTaxonomyLevel(level2); + dbInstance.commitAndCloseSession(); + // access allowed + boolean hasAgainCompetence = documentPoolManager.hasValidCompetence(id); + Assert.assertTrue(hasAgainCompetence); + + //root will be lost + level1.setIdentifier("lost+found"); + level1 = taxonomyLevelDao.updateTaxonomyLevel(level1); + dbInstance.commitAndCloseSession(); + boolean hasLostAgainCompetence = documentPoolManager.hasValidCompetence(id); + Assert.assertFalse(hasLostAgainCompetence); + } + + private TaxonomyLevelType createTypeLevelCompetence(Identity id, TaxonomyLevel parent, TaxonomyCompetenceTypes competenceType) { String levelId = "DP-Lev. " + UUID.randomUUID(); Taxonomy taxonomy = getDocumentPoolTaxonomy(); TaxonomyLevelType type = taxonomyLevelTypeDao.createTaxonomyLevelType("Type-docpool", "A type for document pool", "Typed", "TYP-0", taxonomy); - TaxonomyLevel level = taxonomyLevelDao.createTaxonomyLevel(levelId, "Competence level", "A competence", null, null, null, type, taxonomy); + TaxonomyLevel level = taxonomyLevelDao.createTaxonomyLevel(levelId, "Competence level", "A competence", null, null, parent, type, taxonomy); TaxonomyCompetence competenceTarget = taxonomyCompetenceDao.createTaxonomyCompetence(competenceType, level, id, null); dbInstance.commit(); type.setDocumentsLibraryManageCompetenceEnabled(false); -- GitLab