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