001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.auth.xacml; 019 020import static org.fcrepo.kernel.modeshape.FedoraSessionImpl.getJcrSession; 021import static org.fcrepo.kernel.modeshape.utils.FedoraTypesUtils.isInternalNode; 022import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT; 023import static org.jboss.security.xacml.sunxacml.ctx.Status.STATUS_PROCESSING_ERROR; 024 025import java.util.HashMap; 026import java.util.HashSet; 027import java.util.Set; 028 029import javax.inject.Inject; 030import javax.jcr.Node; 031import javax.jcr.NodeIterator; 032import javax.jcr.RepositoryException; 033 034import org.fcrepo.http.commons.session.SessionFactory; 035import org.fcrepo.kernel.api.FedoraSession; 036 037import org.jboss.security.xacml.sunxacml.EvaluationCtx; 038import org.jboss.security.xacml.sunxacml.attr.AttributeValue; 039import org.jboss.security.xacml.sunxacml.finder.ResourceFinderModule; 040import org.jboss.security.xacml.sunxacml.finder.ResourceFinderResult; 041import org.springframework.stereotype.Component; 042 043 044/** 045 * Locates resources that are subordinate to a Fedora resource. 046 * @author Gregory Jansen 047 * @author Esme Cowles 048 */ 049@Component("fedoraResourceFinderModule") 050public class FedoraResourceFinderModule extends ResourceFinderModule { 051 052 /** 053 * Fedora's ModeShape session factory. 054 */ 055 @Inject 056 protected SessionFactory sessionFactory; 057 058 /* 059 * Does find child resources. 060 * @see org.jboss.security.xacml.sunxacml.finder.ResourceFinderModule# 061 * isChildSupported() 062 */ 063 @Override 064 public final boolean isChildSupported() { 065 return true; 066 } 067 068 /* 069 * Does find descendant resources. 070 * @see org.jboss.security.xacml.sunxacml.finder.ResourceFinderModule# 071 * isDescendantSupported() 072 */ 073 @Override 074 public final boolean isDescendantSupported() { 075 return true; 076 } 077 078 /* 079 * Finds ModeShape child resources based on parent ID and evaluation 080 * context. 081 * @see org.jboss.security.xacml.sunxacml.finder.ResourceFinderModule# 082 * findChildResources(org.jboss.security.xacml.sunxacml.attr.AttributeValue, 083 * org.jboss.security.xacml.sunxacml.EvaluationCtx) 084 */ 085 @Override 086 public final ResourceFinderResult findChildResources( 087 final AttributeValue parentResourceId, 088 final EvaluationCtx context) { 089 return findChildren( parentResourceId, false ); 090 } 091 092 /* 093 * Finds ModeShape descendant resources based on parent ID and evaluation 094 * context. 095 * @see org.jboss.security.xacml.sunxacml.finder.ResourceFinderModule# 096 * findDescendantResources 097 * (org.jboss.security.xacml.sunxacml.attr.AttributeValue, 098 * org.jboss.security.xacml.sunxacml.EvaluationCtx) 099 */ 100 @Override 101 public final ResourceFinderResult findDescendantResources( 102 final AttributeValue parentResourceId, 103 final EvaluationCtx context) { 104 return findChildren( parentResourceId, true ); 105 } 106 107 /** 108 * Find the child resources (or all descendant resources) of a path. 109 * @param parent Repository path to find children of. 110 * @param recurse If true, find all descenant resources, not just direct children. 111 **/ 112 private ResourceFinderResult findChildren( final AttributeValue parent, final boolean recurse ) { 113 try { 114 final FedoraSession session = sessionFactory.getInternalSession(); 115 final Node node = getJcrSession(session).getNode( parent.getValue().toString() ); 116 final Set<String> children = new HashSet<>(); 117 findChildren( node, children, recurse ); 118 return new ResourceFinderResult( children ); 119 } catch ( final RepositoryException ex ) { 120 final HashMap<AttributeValue, String> errors = new HashMap<>(); 121 errors.put( parent, STATUS_PROCESSING_ERROR ); 122 return new ResourceFinderResult( errors ); 123 } 124 } 125 126 /** 127 * Find children of a node. 128 * @param node Repository node to find children of 129 * @param children Set to add child paths to 130 * @param If true, find all descendant paths, not just direct child paths 131 **/ 132 private void findChildren( final Node node, final Set<String> children, final boolean recurse ) 133 throws RepositoryException { 134 for ( final NodeIterator nodes = node.getNodes(); nodes.hasNext(); ) { 135 final Node child = nodes.nextNode(); 136 if ( !isInternalNode.test(child) && !child.getName().equals(JCR_CONTENT) ) { 137 138 children.add( child.getPath() ); 139 140 if ( recurse ) { 141 findChildren( child, children, recurse ); 142 } 143 } 144 } 145 } 146}