/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ro.nextreports.server.dao; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.jcr.Node; import javax.jcr.RepositoryException; import ro.nextreports.server.StorageConstants; import ro.nextreports.server.domain.AclEntry; import ro.nextreports.server.domain.Entity; import ro.nextreports.server.domain.Group; import ro.nextreports.server.domain.User; import ro.nextreports.server.exception.NotFoundException; import ro.nextreports.server.util.AclUtil; import ro.nextreports.server.util.PermissionUtil; import ro.nextreports.server.util.StorageUtil; /** * @author Decebal Suiu */ public class JcrSecurityDao extends AbstractJcrDao implements SecurityDao { private StorageDao storageDao; private AclDao aclDao; public void setStorageDao(StorageDao storageDao) { this.storageDao = storageDao; } public void setAclDao(AclDao aclDao) { this.aclDao = aclDao; } public User[] getUsers() { Entity[] entities = new Entity[0]; try { entities = storageDao.getEntityChildren(StorageConstants.USERS_ROOT); } catch (NotFoundException e) { // never happening e.printStackTrace(); } User[] users = new User[entities.length]; System.arraycopy(entities, 0, users, 0, entities.length); return users; } public User getUserByName(String username) throws NotFoundException { // assert ((username != null) && (username.length() > 0)); String path = StorageConstants.USERS_ROOT.concat(StorageConstants.PATH_SEPARATOR).concat(username); return (User) storageDao.getEntity(path); } public Group[] getGroups() { Entity[] entities = new Entity[0]; try { entities = storageDao.getEntityChildren(StorageConstants.GROUPS_ROOT); } catch (NotFoundException e) { // never happening e.printStackTrace(); } Group[] groups = new Group[entities.length]; System.arraycopy(entities, 0, groups, 0, entities.length); return groups; } public Group getGroupByName(String groupname) throws NotFoundException { // assert ((groupname != null) && (groupname.length() > 0)); String path = StorageConstants.GROUPS_ROOT.concat(StorageConstants.PATH_SEPARATOR).concat(groupname); return (Group) storageDao.getEntity(path); } public AclEntry[] getGranted(String entityPath) { String[] rawAclEntries = aclDao.getRawAclEntries(entityPath); int length = rawAclEntries.length; if (length == 0) { return new AclEntry[0]; } AclEntry[] aclEntries = new AclEntry[length]; for (int i = 0; i < length; i++) { aclEntries[i] = AclUtil.decodeAclEntry(rawAclEntries[i]); } return aclEntries; } public AclEntry[] getGrantedById(String entityId) { String[] rawAclEntries = aclDao.getRawAclEntriesById(entityId); int length = rawAclEntries.length; if (length == 0) { return new AclEntry[0]; } AclEntry[] aclEntries = new AclEntry[length]; for (int i = 0; i < length; i++) { aclEntries[i] = AclUtil.decodeAclEntry(rawAclEntries[i]); } return aclEntries; } public AclEntry[] getGrantedUsers(String entityPath) { // TODO performance ? AclEntry[] aclEntries = getGranted(entityPath); if (aclEntries.length == 0) { return new AclEntry[0]; } List<AclEntry> userAclEntries = new ArrayList<AclEntry>(); for (AclEntry aclEntry : aclEntries) { if (aclEntry.getType() == AclEntry.USER_TYPE) { userAclEntries.add(aclEntry); } } return userAclEntries.toArray(new AclEntry[userAclEntries.size()]); } public AclEntry[] getGrantedUsersById(String entityId) { // TODO performance ? AclEntry[] aclEntries = getGrantedById(entityId); if (aclEntries.length == 0) { return new AclEntry[0]; } List<AclEntry> userAclEntries = new ArrayList<AclEntry>(); for (AclEntry aclEntry : aclEntries) { if (aclEntry.getType() == AclEntry.USER_TYPE) { userAclEntries.add(aclEntry); } } return userAclEntries.toArray(new AclEntry[userAclEntries.size()]); } public void grantUser(String entityPath, String username, int permissions, boolean recursive) throws NotFoundException { AclEntry aclEntry = new AclEntry(AclEntry.USER_TYPE, username, permissions); grantRawAclEntry(entityPath, AclUtil.encodeAclEntry(aclEntry), recursive); } public void revokeUser(String entityPath, String username, int permissions) { AclEntry aclEntry = new AclEntry(AclEntry.USER_TYPE, username, permissions); revokeRawAclEntry(entityPath, AclUtil.encodeAclEntry(aclEntry)); } public AclEntry[] getGrantedGroups(String entityPath) { // TODO performance ? AclEntry[] aclEntries = getGranted(entityPath); if (aclEntries.length == 0) { return new AclEntry[0]; } List<AclEntry> groupAclEntries = new ArrayList<AclEntry>(); for (AclEntry aclEntry : aclEntries) { if (aclEntry.getType() == AclEntry.GROUP_TYPE) { groupAclEntries.add(aclEntry); } } return groupAclEntries.toArray(new AclEntry[groupAclEntries.size()]); } public void grantGroup(String entityPath, String groupname, int permissions, boolean recursive) throws NotFoundException { AclEntry aclEntry = new AclEntry(AclEntry.GROUP_TYPE, groupname, permissions); grantRawAclEntry(entityPath, AclUtil.encodeAclEntry(aclEntry), recursive); } public void revokeGroup(String entityPath, String groupname, int permissions) { AclEntry aclEntry = new AclEntry(AclEntry.GROUP_TYPE, groupname, permissions); revokeRawAclEntry(entityPath, AclUtil.encodeAclEntry(aclEntry)); } private void grantNodeRawAclEntry(String entityPath, String rawAclEntry, boolean add) { Node node = getNode(entityPath); if (isVersionable(node)) { try { getSession().getWorkspace().getVersionManager().checkout(entityPath); } catch (RepositoryException e) { throw convertJcrAccessException(e); } } String[] rawAclEntries = aclDao.getRawAclEntries(entityPath); int length = rawAclEntries.length; // TODO performance ? List<String> rawAclEntryList = new ArrayList<String>(Arrays.asList(rawAclEntries)); boolean isNew = true; for (int i = 0; i < length; i++) { String tmp = rawAclEntryList.get(i); if (AclUtil.getType(rawAclEntry) != AclUtil.getType(tmp)) { continue; } if (!AclUtil.getName(rawAclEntry).equals(AclUtil.getName(tmp))) { continue; } if (!add) { rawAclEntryList.set(i, rawAclEntry); } else { // new acl entry is added to existing ones AclEntry oldEntry = AclUtil.decodeAclEntry(tmp); AclEntry newEntry = AclUtil.decodeAclEntry(rawAclEntry); newEntry.setPermissions(newEntry.getPermissions() | oldEntry.getPermissions()); rawAclEntryList.set(i, AclUtil.encodeAclEntry(newEntry)); } System.out.println("upgrade acl entry '" + tmp + "' with '" + rawAclEntry + "'"); isNew = false; break; } if (isNew) { System.out.println("add acl entry '" + rawAclEntry + "'"); rawAclEntryList.add(rawAclEntry); } rawAclEntries = rawAclEntryList.toArray(rawAclEntries); try { node.setProperty("acl", rawAclEntries); } catch (RepositoryException e) { throw convertJcrAccessException(e); } } /* private void grantNodeRawAclEntryById(String entityId, String rawAclEntry, boolean add) { Node node = getNodeById(entityId); if (isVersionable(node)) { try { getSession().getWorkspace().getVersionManager().checkout(node.getPath()); } catch (RepositoryException e) { throw convertJcrAccessException(e); } } String[] rawAclEntries = aclDao.getRawAclEntriesById(entityId); int length = rawAclEntries.length; // TODO performance ? List<String> rawAclEntryList = new ArrayList<String>(Arrays.asList(rawAclEntries)); boolean isNew = true; for (int i = 0; i < length; i++) { String tmp = rawAclEntryList.get(i); if (AclUtil.getType(rawAclEntry) != AclUtil.getType(tmp)) { continue; } if (!AclUtil.getName(rawAclEntry).equals(AclUtil.getName(tmp))) { continue; } if (!add) { rawAclEntryList.set(i, rawAclEntry); } else { // new acl entry is added to existing ones AclEntry oldEntry = AclUtil.decodeAclEntry(tmp); AclEntry newEntry = AclUtil.decodeAclEntry(rawAclEntry); newEntry.setPermissions(newEntry.getPermissions() | oldEntry.getPermissions()); rawAclEntryList.set(i, AclUtil.encodeAclEntry(newEntry)); } System.out.println("upgrade acl entry '" + tmp + "' with '" + rawAclEntry + "'"); isNew = false; break; } if (isNew) { System.out.println("add acl entry '" + rawAclEntry + "'"); rawAclEntryList.add(rawAclEntry); } rawAclEntries = rawAclEntryList.toArray(rawAclEntries); try { node.setProperty("acl", rawAclEntries); } catch (RepositoryException e) { throw convertJcrAccessException(e); } } */ private void grantRecursiveRawAclEntry(String entityPath, String rawAclEntry) throws NotFoundException { Entity[] children = storageDao.getEntityChildren(entityPath); if (children.length == 0) { return; } for (Entity child : children) { grantNodeRawAclEntry(child.getPath(), rawAclEntry, false); grantRecursiveRawAclEntry(child.getPath(), rawAclEntry); } } /* private void grantRecursiveRawAclEntryById(String entityId, String rawAclEntry) throws NotFoundException { Entity[] children = storageDao.getEntityChildrenById(entityId); if (children.length == 0) { return; } for (Entity child : children) { grantNodeRawAclEntryById(child.getId(), rawAclEntry, false); grantRecursiveRawAclEntryById(child.getId(), rawAclEntry); } } */ private void grantRawAclEntry(String entityPath, String rawAclEntry, boolean recursive) throws NotFoundException { grantNodeRawAclEntry(entityPath, rawAclEntry, false); int permissions = 0; permissions = PermissionUtil.setRead(permissions); AclEntry aclEntry = new AclEntry(AclUtil.getType(rawAclEntry), AclUtil.getName(rawAclEntry), permissions); // grant read to all parent nodes String pPath = entityPath; while(true) { String parentPath = StorageUtil.getParentPath(pPath); if (StorageUtil.isSystemPath(parentPath)) { break; } grantNodeRawAclEntry(parentPath, AclUtil.encodeAclEntry(aclEntry), true); pPath = parentPath; } // recursive grant to all children if (recursive) { grantRecursiveRawAclEntry(entityPath, rawAclEntry); } getTemplate().save(); } private void revokeRawAclEntry(String entityPath, String rawAclEntry) { Node node = getNode(entityPath); if (isVersionable(node)) { try { getSession().getWorkspace().getVersionManager().checkout(entityPath); } catch (RepositoryException e) { throw convertJcrAccessException(e); } } String[] rawAclEntries = aclDao.getRawAclEntries(entityPath); // TODO performance ? List<String> rawAclEntryList = new ArrayList<String>(Arrays.asList(rawAclEntries)); if (rawAclEntryList.contains(rawAclEntry)) { System.out.println("remove acl entry '" + rawAclEntry + "'"); rawAclEntryList.remove(rawAclEntry); rawAclEntries = rawAclEntryList.toArray(rawAclEntries); try { node.setProperty("acl", rawAclEntries); } catch (RepositoryException e) { throw convertJcrAccessException(e); } getTemplate().save(); } } }