001/* 002 * The contents of this file are subject to the license and copyright 003 * detailed in the LICENSE and NOTICE files at the root of the source 004 * tree. 005 */ 006package org.fcrepo.kernel.impl.services; 007 008import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_WEBAC_ACL_URI; 009import static org.fcrepo.kernel.api.rdf.DefaultRdfStream.fromModel; 010 011import java.util.Optional; 012 013import javax.inject.Inject; 014 015import org.fcrepo.kernel.api.RdfStream; 016import org.fcrepo.kernel.api.Transaction; 017import org.fcrepo.kernel.api.auth.ACLHandle; 018import org.fcrepo.kernel.api.exception.PathNotFoundException; 019import org.fcrepo.kernel.api.exception.PathNotFoundRuntimeException; 020import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 021import org.fcrepo.kernel.api.identifiers.FedoraId; 022import org.fcrepo.kernel.api.models.ResourceFactory; 023import org.fcrepo.kernel.api.models.WebacAcl; 024import org.fcrepo.kernel.api.operations.RdfSourceOperation; 025import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory; 026import org.fcrepo.kernel.api.services.WebacAclService; 027import org.fcrepo.kernel.impl.models.WebacAclImpl; 028import org.fcrepo.persistence.api.PersistentStorageSession; 029import org.fcrepo.persistence.api.PersistentStorageSessionManager; 030import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 031import org.springframework.stereotype.Component; 032 033import org.apache.jena.rdf.model.Model; 034 035import com.github.benmanes.caffeine.cache.Cache; 036 037/** 038 * Implementation of {@link WebacAclService} 039 * 040 * @author dbernstein 041 */ 042@Component 043public class WebacAclServiceImpl extends AbstractService implements WebacAclService { 044 045 @Inject 046 private PersistentStorageSessionManager psManager; 047 048 @Inject 049 private ResourceFactory resourceFactory; 050 051 @Inject 052 private RdfSourceOperationFactory rdfSourceOperationFactory; 053 054 @Inject 055 private Cache<String, Optional<ACLHandle>> authHandleCache; 056 057 @Override 058 public WebacAcl find(final Transaction transaction, final FedoraId fedoraId) { 059 try { 060 return resourceFactory.getResource(transaction, fedoraId, WebacAclImpl.class); 061 } catch (final PathNotFoundException exc) { 062 throw new PathNotFoundRuntimeException(exc.getMessage(), exc); 063 } 064 } 065 066 @Override 067 public void create(final Transaction transaction, final FedoraId fedoraId, final String userPrincipal, 068 final Model model) { 069 final PersistentStorageSession pSession = this.psManager.getSession(transaction); 070 071 ensureValidACLAuthorization(model); 072 073 final RdfStream stream = fromModel(model.getResource(fedoraId.getFullId()).asNode(), model); 074 075 final RdfSourceOperation createOp = rdfSourceOperationFactory 076 .createBuilder(transaction, fedoraId, FEDORA_WEBAC_ACL_URI, 077 fedoraPropsConfig.getServerManagedPropsMode()) 078 .parentId(fedoraId.asBaseId()) 079 .triples(stream) 080 .relaxedProperties(model) 081 .userPrincipal(userPrincipal) 082 .build(); 083 084 lockParent(transaction, pSession, fedoraId.asBaseId()); 085 transaction.lockResource(fedoraId); 086 087 try { 088 pSession.persist(createOp); 089 recordEvent(transaction, fedoraId, createOp); 090 // Flush ACL cache on any ACL creation/update/deletion. 091 authHandleCache.invalidateAll(); 092 } catch (final PersistentStorageException exc) { 093 throw new RepositoryRuntimeException(String.format("failed to create resource %s", fedoraId), exc); 094 } 095 } 096 097}