@Override public void performAdditionalStatements(Connection connection) throws SQLException { // Warn user if BROWSE permissions has changed Set<String> dbPermissions = new HashSet<String>(); String sql = "SELECT * FROM aclr_permission"; Statement s = connection.createStatement(); ResultSet rs = s.executeQuery(sql); while (rs.next()) { dbPermissions.add(rs.getString(1)); } rs.close(); s.close(); Set<String> confPermissions = new HashSet<String>(); SecurityService securityService = NXCore.getSecurityService(); for (String perm : securityService.getPermissionsToCheck(SecurityConstants.BROWSE)) { confPermissions.add(perm); } if (!dbPermissions.equals(confPermissions)) { log.error( "Security permission for BROWSE has changed, you need to rebuild the optimized read acls:" + "DROP TABLE aclr_permission; DROP TABLE aclr; then restart."); } }
@Override public Map<String, Serializable> getSQLStatementsProperties(Model model, Database database) { Map<String, Serializable> properties = new HashMap<String, Serializable>(); switch (idType) { case VARCHAR: properties.put("idType", "varchar(36)"); properties.put("idTypeParam", "varchar"); properties.put("idNotPresent", "'-'"); properties.put("sequenceEnabled", Boolean.FALSE); break; case UUID: properties.put("idType", "uuid"); properties.put("idTypeParam", "uuid"); properties.put("idNotPresent", "'00000000-FFFF-FFFF-FFFF-FFFF00000000'"); properties.put("sequenceEnabled", Boolean.FALSE); break; case SEQUENCE: properties.put("idType", "int8"); properties.put("idTypeParam", "int8"); properties.put("idNotPresent", "-1"); properties.put("sequenceEnabled", Boolean.TRUE); properties.put("idSequenceName", idSequenceName); } properties.put("aclOptimizationsEnabled", Boolean.valueOf(aclOptimizationsEnabled)); properties.put("pathOptimizationsEnabled", Boolean.valueOf(pathOptimizationsEnabled)); properties.put("fulltextAnalyzer", fulltextAnalyzer); properties.put("fulltextEnabled", Boolean.valueOf(!fulltextSearchDisabled)); properties.put("clusteringEnabled", Boolean.valueOf(clusteringEnabled)); properties.put("proxiesEnabled", Boolean.valueOf(proxiesEnabled)); properties.put("softDeleteEnabled", Boolean.valueOf(softDeleteEnabled)); if (!fulltextDisabled) { Table ft = database.getTable(model.FULLTEXT_TABLE_NAME); properties.put("fulltextTable", ft.getQuotedName()); FulltextConfiguration fti = model.getFulltextConfiguration(); List<String> lines = new ArrayList<String>(fti.indexNames.size()); for (String indexName : fti.indexNames) { String suffix = model.getFulltextIndexSuffix(indexName); Column ftft = ft.getColumn(model.FULLTEXT_FULLTEXT_KEY + suffix); Column ftst = ft.getColumn(model.FULLTEXT_SIMPLETEXT_KEY + suffix); Column ftbt = ft.getColumn(model.FULLTEXT_BINARYTEXT_KEY + suffix); String concat; if (compatibilityFulltextTable) { // tsvector concat = " NEW.%s := COALESCE(NEW.%s, ''::TSVECTOR) || COALESCE(NEW.%s, ''::TSVECTOR);"; } else { // text with space at beginning and end concat = " NEW.%s := ' ' || COALESCE(NEW.%s, '') || ' ' || COALESCE(NEW.%s, '') || ' ';"; } String line = String.format(concat, ftft.getQuotedName(), ftst.getQuotedName(), ftbt.getQuotedName()); lines.add(line); } properties.put("fulltextTriggerStatements", StringUtils.join(lines, "\n")); } String[] permissions = NXCore.getSecurityService().getPermissionsToCheck(SecurityConstants.BROWSE); List<String> permsList = new LinkedList<String>(); for (String perm : permissions) { permsList.add("('" + perm + "')"); } properties.put("readPermissions", StringUtils.join(permsList, ", ")); properties.put("usersSeparator", getUsersSeparator()); properties.put("everyone", SecurityConstants.EVERYONE); properties.put("readAclMaxSize", Integer.toString(readAclMaxSize)); properties.put("unlogged", unloggedKeyword); return properties; }
@Test public void testReadAclSecurity() { // Check that all permissions that contain Browse enable to list a // document using aclOptimization SecurityService securityService = NXCore.getSecurityService(); String[] browsePermissions = securityService.getPermissionsToCheck(BROWSE); // Check for test permission contribution assertTrue(Arrays.asList(browsePermissions).contains("ViewTest")); List<String> docNames = new ArrayList<String>(browsePermissions.length); DocumentModel root = session.getRootDocument(); for (String permission : browsePermissions) { // Create a folder with only the browse permission String name = "joe-has-" + permission + "-permission"; docNames.add(name); DocumentModel folder = new DocumentModelImpl(root.getPathAsString(), name, "Folder"); folder = session.createDocument(folder); ACP acp = folder.getACP(); assertNotNull(acp); // the acp inherited from root is returned acp = new ACPImpl(); ACL acl = new ACLImpl(); acl.add(new ACE("joe", permission, true)); acp.addACL(acl); folder.setACP(acp, true); } session.save(); CoreSession joeSession = openSessionAs("joe"); try { DocumentModelList list; list = joeSession.query("SELECT * FROM Folder"); List<String> names = new ArrayList<String>(); for (DocumentModel doc : list) { names.add(doc.getName()); } assertEquals( "Expecting " + docNames + " got " + names, browsePermissions.length, list.size()); list = joeSession.query("SELECT * FROM Folder WHERE ecm:isProxy = 0"); names.clear(); for (DocumentModel doc : list) { names.add(doc.getName()); } assertEquals( "Expecting " + docNames + " got " + names, browsePermissions.length, list.size()); // Add a new folder to update the read acls DocumentModel folder = new DocumentModelImpl(root.getPathAsString(), "new-folder", "Folder"); folder = session.createDocument(folder); ACP acp = folder.getACP(); assertNotNull(acp); // the acp inherited from root is returned acp = new ACPImpl(); ACL acl = new ACLImpl(); acl.add(new ACE("joe", browsePermissions[0], true)); acl.add(new ACE("bob", browsePermissions[0], true)); acp.addACL(acl); folder.setACP(acp, true); session.save(); list = joeSession.query("SELECT * FROM Folder"); assertEquals(browsePermissions.length + 1, list.size()); } finally { closeSession(joeSession); } }