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.common;
019
020import static org.junit.Assert.assertEquals;
021import static org.junit.Assert.assertFalse;
022import static org.junit.Assert.assertTrue;
023import static org.mockito.Matchers.any;
024import static org.mockito.Mockito.mock;
025import static org.mockito.Mockito.verify;
026import static org.mockito.Mockito.when;
027import static org.modeshape.jcr.api.JcrConstants.JCR_CONTENT;
028
029import java.security.Principal;
030
031import javax.jcr.Session;
032import javax.servlet.http.HttpServletRequest;
033
034import org.junit.Before;
035import org.junit.Test;
036import org.junit.runner.RunWith;
037import org.mockito.Mock;
038import org.mockito.runners.MockitoJUnitRunner;
039import org.modeshape.jcr.security.AdvancedAuthorizationProvider.Context;
040import org.modeshape.jcr.value.Path;
041
042/**
043 * @author bbpennel
044 * @since Feb 12, 2014
045 */
046@RunWith(MockitoJUnitRunner.class)
047public class FedoraUserSecurityContextTest {
048
049    @Mock
050    private FedoraAuthorizationDelegate fad;
051
052    @Mock
053    private Principal principal;
054
055    @Mock
056    private Principal everyone;
057
058    @Mock
059    private HttpServletRequest request;
060
061    @Before
062    public void setUp() {
063        when(request.getUserPrincipal()).thenReturn(principal);
064        when(fad.getEveryonePrincipal()).thenReturn(everyone);
065        when(everyone.getName()).thenReturn("EVERYONE");
066    }
067
068    @SuppressWarnings("unused")
069    @Test(expected = IllegalArgumentException.class)
070    public void testNoFAD() {
071        new FedoraUserSecurityContext(principal, null);
072    }
073
074    @Test
075    public void testIsNotAnonymous() {
076        final FedoraUserSecurityContext context =
077                new FedoraUserSecurityContext(principal, fad);
078        assertFalse(context.isAnonymous());
079    }
080
081    @Test
082    public void testIsAnonymous() {
083        final FedoraUserSecurityContext context =
084                new FedoraUserSecurityContext(null, fad);
085        assertTrue(context.isAnonymous());
086    }
087
088    @Test
089    public void testGetEffectiveUserPrincipal() {
090        FedoraUserSecurityContext context =
091                new FedoraUserSecurityContext(principal, fad);
092
093        assertEquals("Effective user principal must match given principal",
094                principal, context.getEffectiveUserPrincipal());
095
096        context.logout();
097        assertEquals("User principal when logged out should be EVERYONE",
098                fad.getEveryonePrincipal(), context
099                .getEffectiveUserPrincipal());
100
101        context = new FedoraUserSecurityContext(null, fad);
102
103        assertEquals(
104                "Effective user principal should be EVERYONE when none is provided",
105                fad.getEveryonePrincipal(), context
106                .getEffectiveUserPrincipal());
107    }
108
109    @Test
110    public void testGetAnonymousUserName() {
111        final FedoraUserSecurityContext context =
112                new FedoraUserSecurityContext(null, fad);
113        assertEquals(fad.getEveryonePrincipal().getName(),
114                context.getUserName());
115    }
116
117    @Test
118    public void testGetUserName() {
119        when(principal.getName()).thenReturn("username");
120        final FedoraUserSecurityContext context =
121                new FedoraUserSecurityContext(principal, fad);
122        assertEquals("username", context.getUserName());
123    }
124
125    @Test
126    public void testHasRole() {
127        final FedoraUserSecurityContext context =
128                new FedoraUserSecurityContext(principal, fad);
129
130        assertTrue(context.hasRole("read"));
131        assertTrue(context.hasRole("write"));
132        assertTrue(context.hasRole("admin"));
133        assertFalse(context.hasRole(null));
134        assertFalse(context.hasRole("other"));
135    }
136
137    @Test(expected = NullPointerException.class)
138    public void testHasPermissionNullActions() {
139        final FedoraUserSecurityContext context =
140                new FedoraUserSecurityContext(principal, fad);
141
142        context.hasPermission(null, null, (String[]) null);
143    }
144
145    @Test
146    public void testHasPermission() {
147        final FedoraUserSecurityContext context =
148                new FedoraUserSecurityContext(principal, fad);
149
150        assertFalse("Granted write permission on root", context.hasPermission(
151                null, null, new String[] {"write"}));
152
153        assertTrue("Failed to granted read permission on root", context
154                .hasPermission(null, null, new String[] {"read"}));
155
156        assertTrue("Failed to grant register_namespace permission", context
157                .hasPermission(null, null, new String[] {"register_namespace"}));
158
159        assertTrue("Failed to grant register_type permission", context
160                .hasPermission(null, null, new String[] {"register_type"}));
161
162        assertFalse("Granted write permission on root", context.hasPermission(
163                null, null, new String[] {"read", "write"}));
164
165        when(fad.hasPermission(any(Session.class), any(Path.class), any(String[].class))).thenReturn(true);
166
167        final Path path = mock(Path.class);
168        final Path.Segment segment = mock(Path.Segment.class);
169        when(path.getLastSegment()).thenReturn(segment);
170        when(segment.getString()).thenReturn("junk");
171        assertTrue(context.hasPermission(mock(Context.class), path, new String[] {"read"}));
172        verify(fad).hasPermission(any(Session.class), any(Path.class), any(String[].class));
173
174        context.logout();
175        assertFalse("Granted permission when the context was logged out",
176                context.hasPermission(null, path, new String[] {"read"}));
177    }
178
179    @Test
180    public void testHasPermissionBinary() {
181        final FedoraUserSecurityContext context = new FedoraUserSecurityContext(principal, fad);
182
183        final Path path = mock(Path.class);
184        final Path.Segment segment = mock(Path.Segment.class);
185        when(path.getLastSegment()).thenReturn(segment);
186        when(segment.getString()).thenReturn(JCR_CONTENT);
187        when(path.size()).thenReturn(2);
188        when(path.subpath(0, 1)).thenReturn(path);
189
190        when(fad.hasPermission(any(Session.class), any(Path.class), any(String[].class))).thenReturn(true);
191
192        assertTrue(context.hasPermission(mock(Context.class), path, "read"));
193    }
194
195}