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.webac;
019
020import static org.fcrepo.auth.webac.URIConstants.WEBAC_ACCESS_CONTROL_VALUE;
021import static org.fcrepo.kernel.api.RdfCollectors.toModel;
022import static org.fcrepo.kernel.api.RequiredRdfContext.PROPERTIES;
023import static org.slf4j.LoggerFactory.getLogger;
024import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
025
026import java.net.URI;
027
028import javax.inject.Inject;
029import javax.jcr.Session;
030import javax.ws.rs.core.Link;
031import javax.ws.rs.core.UriInfo;
032
033import org.fcrepo.http.commons.api.UriAwareHttpHeaderFactory;
034import org.fcrepo.http.commons.session.SessionFactory;
035import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
036import org.fcrepo.kernel.api.models.FedoraResource;
037import org.fcrepo.kernel.api.services.NodeService;
038import org.fcrepo.kernel.modeshape.rdf.impl.DefaultIdentifierTranslator;
039
040import org.slf4j.Logger;
041
042import com.google.common.collect.ArrayListMultimap;
043import com.google.common.collect.ListMultimap;
044import com.google.common.collect.Multimap;
045import com.hp.hpl.jena.rdf.model.Resource;
046
047import org.springframework.stereotype.Component;
048
049/**
050 * Insert WebAC Link headers to responses
051 *
052 * @author whikloj
053 * @since 2015-10-30
054 */
055@Component
056public class LinkHeaderProvider implements UriAwareHttpHeaderFactory {
057
058    private static final Logger LOGGER = getLogger(LinkHeaderProvider.class);
059
060    @Inject
061    private SessionFactory sessionFactory;
062
063    @Inject
064    private NodeService nodeService;
065
066    @Override
067    public Multimap<String, String> createHttpHeadersForResource(final UriInfo uriInfo, final FedoraResource resource) {
068
069        final Session internalSession = sessionFactory.getInternalSession();
070        final IdentifierConverter<Resource, FedoraResource> translator =
071                new DefaultIdentifierTranslator(internalSession);
072        final ListMultimap<String, String> headers = ArrayListMultimap.create();
073
074        LOGGER.debug("Adding WebAC Link Header for Resource: {}", resource);
075        // Get the correct Acl for this resource
076        WebACRolesProvider.getEffectiveAcl(resource).ifPresent(acls -> {
077            // If the Acl is present we need to use the internal session to get its URI
078            nodeService.find(internalSession, acls.resource.getPath())
079            .getTriples(translator, PROPERTIES)
080            .collect(toModel()).listObjectsOfProperty(createProperty(WEBAC_ACCESS_CONTROL_VALUE))
081            .forEachRemaining(linkObj -> {
082                if (linkObj.isURIResource()) {
083                    final Resource acl = linkObj.asResource();
084                    final String aclPath = translator.convert(acl).getPath();
085                    final URI aclUri = uriInfo.getBaseUriBuilder().path(aclPath).build();
086                    headers.put("Link", Link.fromUri(aclUri).rel("acl").build().toString());
087                }
088            });
089        });
090
091        return headers;
092    }
093
094
095}