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.integration; 019 020import static org.junit.Assert.assertEquals; 021import static org.mockito.Matchers.any; 022import static org.mockito.Matchers.eq; 023import static org.mockito.Mockito.atLeastOnce; 024import static org.mockito.Mockito.mock; 025import static org.mockito.Mockito.verify; 026import static org.mockito.Mockito.when; 027import static org.slf4j.LoggerFactory.getLogger; 028 029import java.security.Principal; 030 031import javax.inject.Inject; 032import javax.jcr.AccessDeniedException; 033import javax.jcr.Repository; 034import javax.jcr.RepositoryException; 035import javax.jcr.Session; 036import javax.servlet.http.HttpServletRequest; 037 038import org.apache.http.auth.BasicUserPrincipal; 039import org.fcrepo.auth.common.FedoraAuthorizationDelegate; 040import org.fcrepo.auth.common.ServletContainerAuthenticationProvider; 041import org.fcrepo.kernel.api.exception.RepositoryRuntimeException; 042import org.fcrepo.kernel.api.services.ContainerService; 043import org.fcrepo.kernel.modeshape.services.ContainerServiceImpl; 044import org.junit.Assert; 045import org.junit.Test; 046import org.junit.runner.RunWith; 047import org.mockito.Mockito; 048import org.modeshape.jcr.api.ServletCredentials; 049import org.modeshape.jcr.value.Path; 050import org.slf4j.Logger; 051import org.springframework.test.context.ContextConfiguration; 052import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 053 054/** 055 * @author Peter Eichman 056 */ 057@RunWith(SpringJUnit4ClassRunner.class) 058@ContextConfiguration(locations = { "/spring-test/mocked-fad-repo-3.xml" }) 059public class DelegatedUserIT { 060 061 private static Logger logger = 062 getLogger(DelegatedUserIT.class); 063 064 @Inject 065 private Repository repo; 066 067 @Inject 068 private FedoraAuthorizationDelegate fad; 069 070 private final HttpServletRequest request = mock(HttpServletRequest.class); 071 072 @Test 073 public void testFactory() { 074 Assert.assertNotNull( 075 "AuthenticationProvider must return a AuthenticationProvider", 076 ServletContainerAuthenticationProvider.getInstance()); 077 } 078 079 @Test 080 public void testDelegatedUserAccess() throws RepositoryException { 081 082 // mock request by an admin user, on behalf of a regular user 083 when(request.getRemoteUser()).thenReturn("admin1"); 084 when(request.getUserPrincipal()).thenReturn(new BasicUserPrincipal("admin1")); 085 when(request.isUserInRole(eq(ServletContainerAuthenticationProvider.FEDORA_ADMIN_ROLE))).thenReturn(true); 086 when(request.getHeader("On-Behalf-Of")).thenReturn("user1"); 087 088 Mockito.reset(fad); 089 // set up a restrictive mock FAD, which should deny non-admin users 090 when(fad.hasPermission(any(Session.class), any(Path.class), any(String[].class))).thenReturn(false); 091 092 final ServletCredentials credentials = new ServletCredentials(request); 093 final Session session = repo.login(credentials); 094 assertEquals("Session user principal is user1", 095 "user1", 096 ((Principal) session.getAttribute(FedoraAuthorizationDelegate.FEDORA_USER_PRINCIPAL)).getName()); 097 098 // try to create an object, this should fail because it is being executed as a non-admin user 099 final ContainerService os = new ContainerServiceImpl(); 100 try { 101 os.findOrCreate(session, "/myobject"); 102 } catch (final RepositoryRuntimeException e) { 103 final Throwable cause = e.getCause(); 104 if (cause != null && cause instanceof AccessDeniedException) { 105 logger.debug("caught expected access denied exception"); 106 } else { 107 throw e; 108 } 109 } 110 verify(fad, atLeastOnce()).hasPermission(any(Session.class), any(Path.class), any(String[].class)); 111 } 112 113}