/* * 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 org.apache.jackrabbit.core.security.authorization.acl; import java.security.Principal; import java.security.acl.Group; import java.util.ArrayList; import java.util.List; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Value; import org.apache.jackrabbit.api.JackrabbitWorkspace; import org.apache.jackrabbit.api.security.principal.PrincipalManager; import org.apache.jackrabbit.core.NodeImpl; import org.apache.jackrabbit.core.SessionImpl; import org.apache.jackrabbit.core.id.NodeId; import org.apache.jackrabbit.core.security.authorization.AccessControlConstants; import org.apache.jackrabbit.core.security.authorization.GlobPattern; import org.apache.jackrabbit.core.security.authorization.PrivilegeBits; import org.apache.jackrabbit.core.security.authorization.PrivilegeManagerImpl; import org.apache.jackrabbit.core.value.InternalValue; import org.apache.jackrabbit.spi.Name; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Entry... TODO */ class Entry implements AccessControlConstants { private static final Logger log = LoggerFactory.getLogger(Entry.class); private final String principalName; private final boolean isGroupEntry; private final PrivilegeBits privilegeBits; private final boolean isAllow; private final NodeId id; private final GlobPattern pattern; private final boolean hasRestrictions; private int hashCode; private Entry(NodeId id, String principalName, boolean isGroupEntry, PrivilegeBits privilegeBits, boolean allow, String path, Value globValue) throws RepositoryException { this.principalName = principalName; this.isGroupEntry = isGroupEntry; this.privilegeBits = privilegeBits; this.isAllow = allow; this.id = id; this.pattern = calculatePattern(path, globValue); this.hasRestrictions = (globValue != null); } static List<Entry> readEntries(NodeImpl aclNode, String path) throws RepositoryException { if (aclNode == null || !NT_REP_ACL.equals(aclNode.getPrimaryNodeTypeName())) { throw new IllegalArgumentException("Node must be of type 'rep:ACL'"); } SessionImpl sImpl = (SessionImpl) aclNode.getSession(); PrincipalManager principalMgr = sImpl.getPrincipalManager(); PrivilegeManagerImpl privilegeMgr = (PrivilegeManagerImpl) ((JackrabbitWorkspace) sImpl.getWorkspace()).getPrivilegeManager(); NodeId nodeId = aclNode.getParentId(); List<Entry> entries = new ArrayList<Entry>(); // load the entries: NodeIterator itr = aclNode.getNodes(); while (itr.hasNext()) { NodeImpl aceNode = (NodeImpl) itr.nextNode(); try { String principalName = aceNode.getProperty(P_PRINCIPAL_NAME).getString(); boolean isGroupEntry = false; Principal princ = principalMgr.getPrincipal(principalName); if (princ != null) { isGroupEntry = (princ instanceof Group); } InternalValue[] privValues = aceNode.getProperty(P_PRIVILEGES).internalGetValues(); Name[] privNames = new Name[privValues.length]; for (int i = 0; i < privValues.length; i++) { privNames[i] = privValues[i].getName(); } Value globValue = null; if (aceNode.hasProperty(P_GLOB)) { globValue = aceNode.getProperty(P_GLOB).getValue(); } boolean isAllow = NT_REP_GRANT_ACE.equals(aceNode.getPrimaryNodeTypeName()); Entry ace = new Entry(nodeId, principalName, isGroupEntry, privilegeMgr.getBits(privNames), isAllow, path, globValue); entries.add(ace); } catch (RepositoryException e) { log.debug("Failed to build ACE from content. {}", e.getMessage()); } } return entries; } private static GlobPattern calculatePattern(String path, Value globValue) throws RepositoryException { if (path == null) { return null; } else { if (globValue == null) { return GlobPattern.create(path); } else { return GlobPattern.create(path, globValue.getString()); } } } /** * @param nodeId * @return <code>true</code> if this entry is defined on the node * at <code>nodeId</code> */ boolean isLocal(NodeId nodeId) { return id != null && id.equals(nodeId); } /** * * @param jcrPath * @return */ boolean matches(String jcrPath) { return pattern != null && pattern.matches(jcrPath); } PrivilegeBits getPrivilegeBits() { return privilegeBits; } boolean isAllow() { return isAllow; } String getPrincipalName() { return principalName; } boolean isGroupEntry() { return isGroupEntry; } boolean hasRestrictions() { return hasRestrictions; } //-------------------------------------------------------------< Object >--- /** * @see Object#hashCode() */ @Override public int hashCode() { if (hashCode == -1) { int h = 17; h = 37 * h + principalName.hashCode(); h = 37 * h + privilegeBits.hashCode(); h = 37 * h + Boolean.valueOf(isAllow).hashCode(); h = 37 * h + pattern.hashCode(); hashCode = h; } return hashCode; } /** * @see Object#equals(Object) */ @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof Entry) { Entry other = (Entry) obj; return principalName.equals(other.principalName) && privilegeBits.equals(other.privilegeBits) && isAllow == other.isAllow && pattern.equals(other.pattern); } return false; } }