diff --git a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java index b8eb0b86433745dff583610e8305b297119fa3d0..c23befcbe5ab706a392fc494415fef49607e40b7 100644 --- a/src/main/java/org/olat/admin/user/course/CourseOverviewController.java +++ b/src/main/java/org/olat/admin/user/course/CourseOverviewController.java @@ -80,6 +80,7 @@ import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryModule; import org.olat.repository.controllers.ReferencableEntriesSearchController; import org.olat.repository.controllers.RepositoryEntryFilter; +import org.olat.repository.controllers.RepositorySearchController.Can; import org.olat.repository.model.RepositoryEntryMembership; import org.olat.repository.model.RepositoryEntryPermissionChangeEvent; @@ -401,7 +402,7 @@ public class CourseOverviewController extends BasicController { RepositoryEntryFilter filter = new ManagedEntryfilter(); repoSearchCtr = new ReferencableEntriesSearchController(getWindowControl(), ureq, new String[]{ CourseModule.getCourseTypeName() }, filter, - translate("choose"), false, false, true, true, true, null); + translate("choose"), false, false, true, true, true, Can.all); repoSearchCtr.setUserObject(type); listenTo(repoSearchCtr); cmc = new CloseableModalController(getWindowControl(), translate("close"), repoSearchCtr.getInitialComponent(), diff --git a/src/main/java/org/olat/modules/sharedfolder/SharedFolderWebDAVMergeSource.java b/src/main/java/org/olat/modules/sharedfolder/SharedFolderWebDAVMergeSource.java index 0afb30e7e1921e7ab2870c8905ca8ca746bf179c..ceaad730a90ea06fbe36ca9a71e0fcab0fa5250c 100644 --- a/src/main/java/org/olat/modules/sharedfolder/SharedFolderWebDAVMergeSource.java +++ b/src/main/java/org/olat/modules/sharedfolder/SharedFolderWebDAVMergeSource.java @@ -22,6 +22,7 @@ package org.olat.modules.sharedfolder; import static org.olat.modules.sharedfolder.SharedFolderWebDAVProvider.readOnlyCallback; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.olat.core.commons.persistence.PersistenceHelper; @@ -107,8 +108,8 @@ public class SharedFolderWebDAVMergeSource extends MergeSource { if (firstItem != null && firstItem.equals("*")) { // fake role that represents normally logged in user Roles registeredUserRole = new Roles(false, false, false, false, false, false, false); - //fxdiff VCRP-1,2: access control of resources - List<RepositoryEntry> allEntries = repoManager.queryByTypeLimitAccess(identity, SharedFolderFileResource.TYPE_NAME, registeredUserRole); + List<String> types = Collections.singletonList(SharedFolderFileResource.TYPE_NAME); + List<RepositoryEntry> allEntries = repoManager.queryByTypeLimitAccess(identity, types, registeredUserRole); for (RepositoryEntry re : allEntries) { String name = Formatter.makeStringFilesystemSave(re.getDisplayname()); if(childName.equals(name)) { @@ -186,9 +187,8 @@ public class SharedFolderWebDAVMergeSource extends MergeSource { if (firstItem != null && firstItem.equals("*")) { // fake role that represents normally logged in user Roles registeredUserRole = new Roles(false, false, false, false, false, false, false); - //fxdiff VCRP-1,2: access control of resources - List<RepositoryEntry> allEntries = repoManager.queryByTypeLimitAccess(identity, SharedFolderFileResource.TYPE_NAME, - registeredUserRole); + List<String> types = Collections.singletonList(SharedFolderFileResource.TYPE_NAME); + List<RepositoryEntry> allEntries = repoManager.queryByTypeLimitAccess(identity, types, registeredUserRole); for (RepositoryEntry entry : allEntries) { addReadonlyFolder(this, entry, sfm, addedEntries); } diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index 81a5de0b9346ce838ab2635ec80b9ae0228aa085..811c3e715f7d69fb83d76e21c6fe1c23bd44b2a9 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -1036,13 +1036,13 @@ public class RepositoryManager extends BasicManager { /** * Query by type, limit by ownership or role accessability. - * @param identity Identity (optional) - * @param restrictedType + * @param identity + * @param restrictedType The type cannot be empty, no type, no return * @param roles - * @return Results + * @return */ - //fxdiff VCRP-1,2: access control of resources - public List<RepositoryEntry> queryByTypeLimitAccess(Identity identity, String restrictedType, Roles roles) { + public List<RepositoryEntry> queryByTypeLimitAccess(Identity identity, List<String> restrictedType, Roles roles) { + if(restrictedType == null | restrictedType.isEmpty()) return Collections.emptyList(); if(roles.isOLATAdmin()) { identity = null;//not need for the query as administrator } @@ -1054,7 +1054,7 @@ public class RepositoryManager extends BasicManager { .append(" left join fetch v.ownerGroup as ownerGroup") .append(" left join fetch v.participantGroup as participantGroup") .append(" left join fetch v.tutorGroup as tutorGroup") - .append(" where res.resName=:restrictedType and "); + .append(" where res.resName in (:restrictedType) and "); boolean setIdentity = false; if (roles.isOLATAdmin()) { @@ -1072,17 +1072,18 @@ public class RepositoryManager extends BasicManager { return query.getResultList(); } + /** * Query by type, limit by ownership or role accessability and institution. - * @param restrictedType + * @param identity * @param roles - * @return Results + * @param restrictedType The types cannot be empty, no type, nothing to return + * @return */ - //fxdiff VCRP-1: access control - public List<RepositoryEntry> queryByTypeLimitAccess(Identity identity, Roles roles, String restrictedType) { - String institution = identity.getUser().getProperty("institutionalName", null); - - //TODO hibernate + public List<RepositoryEntry> queryByTypeLimitAccess(Identity identity, Roles roles, List<String> restrictedType) { + if(restrictedType == null | restrictedType.isEmpty()) return Collections.emptyList(); + + String institution = identity.getUser().getProperty(UserConstants.INSTITUTIONALNAME, null); List<RepositoryEntry> results = new ArrayList<RepositoryEntry>(); if(!roles.isOLATAdmin() && institution != null && institution.length() > 0 && roles.isInstitutionalResourceManager()) { StringBuilder query = new StringBuilder(400); @@ -1095,17 +1096,13 @@ public class RepositoryManager extends BasicManager { + " and sgmsi.identity = identity" + " and identity.user = user" +" and user.properties['institutionalName']= :institutionCourseManager " - + " and res.resName= :restrictedType and v.access = 1"); - - DBQuery dbquery = DBFactory.getInstance().createQuery(query.toString()); - dbquery.setString("restrictedType", restrictedType); - dbquery.setString("institutionCourseManager", institution); - dbquery.setCacheable(true); + + " and res.resName in (:restrictedType) and v.access = 1"); - long start = System.currentTimeMillis(); - List<RepositoryEntry> institutionalResults = dbquery.list(); - long timeQuery1 = System.currentTimeMillis() - start; - logInfo("Repo-Perf: queryByTypeLimitAccess#3 takes " + timeQuery1); + List<RepositoryEntry> institutionalResults = dbInstance.getCurrentEntityManager() + .createQuery(query.toString(), RepositoryEntry.class) + .setParameter("restrictedType", restrictedType) + .setParameter("institutionCourseManager", institution) + .getResultList(); results.addAll(institutionalResults); } diff --git a/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java b/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java index 4f26cf63713645830bd7292c771f7e0080242276..fe0b2f5e9a9f11f8492bd1e8393f9de9792831af 100644 --- a/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java +++ b/src/main/java/org/olat/repository/controllers/ReferencableEntriesSearchController.java @@ -355,6 +355,9 @@ public class ReferencableEntriesSearchController extends BasicController { case copyable: searchCtr.doSearchForCopyableResourcesLimitType(ureq.getIdentity(), limitTypes, ureq.getUserSession().getRoles()); break; + case all: + searchCtr.doSearchByTypeLimitAccess(limitTypes, ureq); + break; } } else if (clickedLink == searchEntriesLink){ searchCtr.displaySearchForm(); diff --git a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java index d432211cabb84d28af6c2422f569cb8c01cb9faf..4148c92b93091821a665df959cdf9e90c19abdac 100644 --- a/src/main/java/org/olat/repository/controllers/RepositorySearchController.java +++ b/src/main/java/org/olat/repository/controllers/RepositorySearchController.java @@ -266,7 +266,6 @@ public class RepositorySearchController extends BasicController implements Activ List<RepositoryEntry> entries = rm.genericANDQueryWithRolesRestriction(params, 0, -1, true); filterRepositoryEntries(entries); repoTableModel.setObjects(entries); - //fxdiff VCRP-10: repository search with type filter if(updateFilters) { updateFilters(entries, null); } @@ -425,29 +424,31 @@ public class RepositorySearchController extends BasicController implements Activ */ public void doSearchByOwnerLimitAccess(Identity owner) { RepositoryManager rm = RepositoryManager.getInstance(); - //fxdiff VCRP-1,2: access control of resources List<RepositoryEntry> entries = rm.queryByOwnerLimitAccess(owner, RepositoryEntry.ACC_USERS, Boolean.TRUE); filterRepositoryEntries(entries); repoTableModel.setObjects(entries); - //fxdiff VCRP-10: repository search with type filter tableCtr.setFilters(null, null); tableCtr.modelChanged(); displaySearchResults(null); } + + protected void doSearchByTypeLimitAccess(String restrictedType, UserRequest ureq) { + doSearchByTypeLimitAccess(new String[]{restrictedType}, ureq); + } /** - * Package private. Used by repository main controller to execute predefined searches. + * Used by repository main controller to execute predefined searches. * - * @param type + * @param restrictedTypes * @param ureq */ - void doSearchByTypeLimitAccess(String type, UserRequest ureq) { + protected void doSearchByTypeLimitAccess(String[] restrictedTypes, UserRequest ureq) { searchType = null; RepositoryManager rm = RepositoryManager.getInstance(); - List<RepositoryEntry> entries = rm.queryByTypeLimitAccess(ureq.getIdentity(), ureq.getUserSession().getRoles(), type); + List<String> types = Arrays.asList(restrictedTypes); + List<RepositoryEntry> entries = rm.queryByTypeLimitAccess(ureq.getIdentity(), ureq.getUserSession().getRoles(), types); filterRepositoryEntries(entries); repoTableModel.setObjects(entries); - //fxdiff VCRP-10: repository search with type filter tableCtr.setFilters(null, null); tableCtr.modelChanged(); displaySearchResults(ureq); @@ -719,6 +720,7 @@ public class RepositorySearchController extends BasicController implements Activ public enum Can { referenceable, - copyable + copyable, + all } } \ No newline at end of file diff --git a/src/test/java/org/olat/repository/RepositoryManagerTest.java b/src/test/java/org/olat/repository/RepositoryManagerTest.java index 9d7af3168cc6410b1695324945227e7e848f2c99..8eb86dea2a5da20fa865ac6c5a7fd2c370aa4a5b 100644 --- a/src/test/java/org/olat/repository/RepositoryManagerTest.java +++ b/src/test/java/org/olat/repository/RepositoryManagerTest.java @@ -492,8 +492,62 @@ public class RepositoryManagerTest extends OlatTestCase { dbInstance.commitAndCloseSession(); //check + List<String> types = Collections.singletonList(re.getOlatResource().getResourceableTypeName()); + List<RepositoryEntry> entries = repositoryManager.queryByTypeLimitAccess(id, + types, new Roles(false, false, false, false, false, false, false)); + + Assert.assertNotNull(entries); + Assert.assertFalse(entries.isEmpty()); + Assert.assertTrue(entries.contains(re)); + for(RepositoryEntry entry:entries) { + if(!entry.equals(re)) { + Assert.assertTrue(entry.getAccess() >= RepositoryEntry.ACC_USERS); + } + } + } + + @Test + public void queryByTypeLimitAccess_withoutInstitution() { + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("qbtla-2-" + UUID.randomUUID().toString()); + RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(true); + BusinessGroup group = businessGroupService.createBusinessGroup(null, "qbtla-2", "tg", null, null, false, false, re); + securityManager.addIdentityToSecurityGroup(id, group.getOwnerGroup()); + dbInstance.commitAndCloseSession(); + + //check + List<String> types = Collections.singletonList(re.getOlatResource().getResourceableTypeName()); + List<RepositoryEntry> entries = repositoryManager.queryByTypeLimitAccess(id, + new Roles(false, false, false, false, false, false, false), types); + + Assert.assertNotNull(entries); + Assert.assertFalse(entries.isEmpty()); + Assert.assertTrue(entries.contains(re)); + for(RepositoryEntry entry:entries) { + if(!entry.equals(re)) { + Assert.assertTrue(entry.getAccess() >= RepositoryEntry.ACC_USERS); + } + } + } + + @Test + public void queryByTypeLimitAccess_withInstitution() { + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("qbtla-3-" + UUID.randomUUID().toString()); + RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(true); + BusinessGroup group = businessGroupService.createBusinessGroup(null, "qbtla-3", "tg", null, null, false, false, re); + securityManager.addIdentityToSecurityGroup(id, group.getOwnerGroup()); + dbInstance.commitAndCloseSession(); + + //promote id to institution resource manager + id.getUser().setProperty(UserConstants.INSTITUTIONALNAME, "openolat.org"); + userManager.updateUserFromIdentity(id); + SecurityGroup institutionalResourceManagerGroup = securityManager.findSecurityGroupByName(Constants.GROUP_INST_ORES_MANAGER); + securityManager.addIdentityToSecurityGroup(id, institutionalResourceManagerGroup); + dbInstance.commitAndCloseSession(); + + //check + List<String> types = Collections.singletonList(re.getOlatResource().getResourceableTypeName()); List<RepositoryEntry> entries = repositoryManager.queryByTypeLimitAccess(id, - re.getOlatResource().getResourceableTypeName(), new Roles(false, false, false, false, false, false, false)); + new Roles(false, false, false, false, false, true, false), types); Assert.assertNotNull(entries); Assert.assertFalse(entries.isEmpty());