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.kernel.impl.services; 019 020import static org.fcrepo.kernel.api.RdfLexicon.FEDORA_WEBAC_ACL_URI; 021import static org.fcrepo.kernel.api.rdf.DefaultRdfStream.fromModel; 022 023import java.util.Optional; 024 025import javax.inject.Inject; 026 027import org.fcrepo.kernel.api.RdfStream; 028import org.fcrepo.kernel.api.Transaction; 029import org.fcrepo.kernel.api.auth.ACLHandle; 030import org.fcrepo.kernel.api.exception.PathNotFoundException; 031import org.fcrepo.kernel.api.exception.PathNotFoundRuntimeException; 032import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 033import org.fcrepo.kernel.api.identifiers.FedoraId; 034import org.fcrepo.kernel.api.models.ResourceFactory; 035import org.fcrepo.kernel.api.models.WebacAcl; 036import org.fcrepo.kernel.api.operations.RdfSourceOperation; 037import org.fcrepo.kernel.api.operations.RdfSourceOperationFactory; 038import org.fcrepo.kernel.api.services.WebacAclService; 039import org.fcrepo.kernel.impl.models.WebacAclImpl; 040import org.fcrepo.persistence.api.PersistentStorageSession; 041import org.fcrepo.persistence.api.PersistentStorageSessionManager; 042import org.fcrepo.persistence.api.exceptions.PersistentStorageException; 043import org.springframework.stereotype.Component; 044 045import org.apache.jena.rdf.model.Model; 046 047import com.github.benmanes.caffeine.cache.Cache; 048 049/** 050 * Implementation of {@link WebacAclService} 051 * 052 * @author dbernstein 053 */ 054@Component 055public class WebacAclServiceImpl extends AbstractService implements WebacAclService { 056 057 @Inject 058 private PersistentStorageSessionManager psManager; 059 060 @Inject 061 private ResourceFactory resourceFactory; 062 063 @Inject 064 private RdfSourceOperationFactory rdfSourceOperationFactory; 065 066 @Inject 067 private Cache<String, Optional<ACLHandle>> authHandleCache; 068 069 @Override 070 public WebacAcl find(final Transaction transaction, final FedoraId fedoraId) { 071 try { 072 return resourceFactory.getResource(transaction, fedoraId, WebacAclImpl.class); 073 } catch (final PathNotFoundException exc) { 074 throw new PathNotFoundRuntimeException(exc.getMessage(), exc); 075 } 076 } 077 078 @Override 079 public void create(final Transaction transaction, final FedoraId fedoraId, final String userPrincipal, 080 final Model model) { 081 final PersistentStorageSession pSession = this.psManager.getSession(transaction); 082 083 ensureValidACLAuthorization(model); 084 085 final RdfStream stream = fromModel(model.getResource(fedoraId.getFullId()).asNode(), model); 086 087 final RdfSourceOperation createOp = rdfSourceOperationFactory 088 .createBuilder(transaction, fedoraId, FEDORA_WEBAC_ACL_URI, 089 fedoraPropsConfig.getServerManagedPropsMode()) 090 .parentId(fedoraId.asBaseId()) 091 .triples(stream) 092 .relaxedProperties(model) 093 .userPrincipal(userPrincipal) 094 .build(); 095 096 lockArchivalGroupResourceFromParent(transaction, pSession, fedoraId.asBaseId()); 097 transaction.lockResource(fedoraId); 098 099 try { 100 pSession.persist(createOp); 101 recordEvent(transaction, fedoraId, createOp); 102 // Flush ACL cache on any ACL creation/update/deletion. 103 authHandleCache.invalidateAll(); 104 } catch (final PersistentStorageException exc) { 105 throw new RepositoryRuntimeException(String.format("failed to create resource %s", fedoraId), exc); 106 } 107 } 108 109}