001/*
002 * Copyright 2015 DuraSpace, Inc.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.fcrepo.auth.webac;
017
018import static org.fcrepo.auth.webac.URIConstants.WEBAC_ACCESS_CONTROL_VALUE;
019import static org.fcrepo.kernel.api.RdfCollectors.toModel;
020import static org.fcrepo.kernel.api.RequiredRdfContext.PROPERTIES;
021import static org.slf4j.LoggerFactory.getLogger;
022import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
023
024import java.net.URI;
025import javax.jcr.Session;
026import javax.ws.rs.core.Link;
027import javax.ws.rs.core.UriInfo;
028
029import org.fcrepo.http.commons.api.UriAwareHttpHeaderFactory;
030import org.fcrepo.http.commons.session.SessionFactory;
031import org.fcrepo.kernel.api.identifiers.IdentifierConverter;
032import org.fcrepo.kernel.api.models.FedoraResource;
033import org.fcrepo.kernel.api.services.NodeService;
034import org.fcrepo.kernel.modeshape.rdf.impl.DefaultIdentifierTranslator;
035
036import org.slf4j.Logger;
037
038import com.google.common.collect.ArrayListMultimap;
039import com.google.common.collect.ListMultimap;
040import com.google.common.collect.Multimap;
041import com.hp.hpl.jena.rdf.model.Resource;
042
043import org.springframework.beans.factory.annotation.Autowired;
044import org.springframework.stereotype.Component;
045
046/**
047 * Insert WebAC Link headers to responses
048 *
049 * @author whikloj
050 * @since 2015-10-30
051 */
052@Component
053public class LinkHeaderProvider implements UriAwareHttpHeaderFactory {
054
055    private static final Logger LOGGER = getLogger(LinkHeaderProvider.class);
056
057    @Autowired
058    private SessionFactory sessionFactory;
059
060    @Autowired
061    private NodeService nodeService;
062
063    @Override
064    public Multimap<String, String> createHttpHeadersForResource(final UriInfo uriInfo, final FedoraResource resource) {
065
066        final Session internalSession = sessionFactory.getInternalSession();
067        final IdentifierConverter<Resource, FedoraResource> translator =
068                new DefaultIdentifierTranslator(internalSession);
069        final ListMultimap<String, String> headers = ArrayListMultimap.create();
070
071        LOGGER.debug("Adding WebAC Link Header for Resource: {}", resource);
072        // Get the correct Acl for this resource
073        WebACRolesProvider.getEffectiveAcl(resource).ifPresent(acls -> {
074            // If the Acl is present we need to use the internal session to get its URI
075            nodeService.find(internalSession, acls.resource.getPath())
076            .getTriples(translator, PROPERTIES)
077            .collect(toModel()).listObjectsOfProperty(createProperty(WEBAC_ACCESS_CONTROL_VALUE))
078            .forEachRemaining(linkObj -> {
079                if (linkObj.isURIResource()) {
080                    final Resource acl = linkObj.asResource();
081                    final String aclPath = translator.convert(acl).getPath();
082                    final URI aclUri = uriInfo.getBaseUriBuilder().path(aclPath).build();
083                    headers.put("Link", Link.fromUri(aclUri).rel("acl").build().toString());
084                }
085            });
086        });
087
088        return headers;
089    }
090
091
092}