/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.uberfire.security.impl.authz; import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import org.jboss.errai.security.shared.api.Role; import org.jboss.errai.security.shared.api.RoleImpl; import org.jboss.errai.security.shared.api.identity.User; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.runners.MockitoJUnitRunner; import org.uberfire.security.ResourceAction; import org.uberfire.security.ResourceRef; import org.uberfire.security.ResourceType; import org.uberfire.security.authz.AuthorizationPolicy; import org.uberfire.security.authz.AuthorizationResult; import org.uberfire.security.authz.Permission; import org.uberfire.security.authz.PermissionCollection; import org.uberfire.security.authz.PermissionManager; import org.uberfire.security.authz.VotingAlgorithm; import org.uberfire.security.authz.VotingStrategy; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import static org.uberfire.security.authz.AuthorizationResult.ACCESS_ABSTAIN; import static org.uberfire.security.authz.AuthorizationResult.ACCESS_DENIED; import static org.uberfire.security.authz.AuthorizationResult.ACCESS_GRANTED; @RunWith(MockitoJUnitRunner.class) public class PermissionManagerTest { PermissionManager permissionManager; DefaultAuthzResultCache authzResultCache; AuthorizationPolicy authorizationPolicy; Permission viewAll = new DotNamedPermission("resource.read", true); Permission denyAll = new DotNamedPermission("resource.read", false); Permission view1 = new DotNamedPermission("resource.read.1", true); Permission noView1 = new DotNamedPermission("resource.read.1", false); Permission view2 = new DotNamedPermission("resource.read.2", true); Permission view12 = new DotNamedPermission("resource.read.1.2", true); protected User createUserMock(String... roles) { User user = mock(User.class); Set<Role> roleSet = Stream.of(roles).map(RoleImpl::new).collect(Collectors.toSet()); when(user.getIdentifier()).thenReturn(Integer.toString(user.hashCode())); when(user.getRoles()).thenReturn(roleSet); when(user.getGroups()).thenReturn(null); return user; } @Before public void setUp() { authzResultCache = spy(new DefaultAuthzResultCache()); permissionManager = spy(new DefaultPermissionManager(new DefaultPermissionTypeRegistry(), authzResultCache)); permissionManager.setAuthorizationPolicy( authorizationPolicy = spy(permissionManager.newAuthorizationPolicy() .role("viewAll").permission("resource.read", true) .role("noViewAll").permission("resource.read", false) .role("onlyView1", 5).permission("resource.read", false).permission("resource.read.1", true) .role("noView1").permission("resource.read.1", false) .role("onlyView12").permission("resource.read.1.2", true) .build())); } @Test public void testSetNullPolicy() { permissionManager.setAuthorizationPolicy(null); AuthorizationPolicy policy = permissionManager.getAuthorizationPolicy(); assertNotNull(policy); assertTrue(policy.getRoles().isEmpty()); assertTrue(policy.getGroups().isEmpty()); } @Test public void testCreateGlobalPermissions() { ResourceType type = () -> "type"; Permission p = permissionManager.createPermission(type, null, true); assertEquals(p.getName(), "type.read"); p = permissionManager.createPermission(type, () -> "edit", true); assertEquals(p.getName(), "type.edit"); } @Test public void testCreateTypedPermissions() { ResourceType type = () -> "type"; ResourceRef r = new ResourceRef("r1", type, null); Permission p = permissionManager.createPermission(r, null, true); assertEquals(p.getName(), "type.read.r1"); p = permissionManager.createPermission(r, ResourceAction.READ, true); assertEquals(p.getName(), "type.read.r1"); } @Test public void testUnknownTypePermissions() { ResourceRef r = new ResourceRef("r1", ResourceType.UNKNOWN, null); Permission p = permissionManager.createPermission(r, null, true); assertEquals(p.getName(), "r1"); p = permissionManager.createPermission(r, ResourceAction.READ, true); assertEquals(p.getName(), "r1"); } @Test public void testCreateNonTypedPermissions() { ResourceRef r = new ResourceRef("r1", null, null); Permission p = permissionManager.createPermission(r, null, true); assertEquals(p.getName(), "r1"); p = permissionManager.createPermission(r, ResourceAction.READ, true); assertEquals(p.getName(), "r1"); } @Test public void testResolveResourceId() { ResourceType type = () -> "type"; ResourceRef r = new ResourceRef("r1", type, null); Permission p = permissionManager.createPermission(r, null, true); assertEquals(p.getName(), "type.read.r1"); String id = permissionManager.resolveResourceId(p); assertEquals(id, "r1"); } @Test public void testResolveResourceNull() { Permission p = permissionManager.createPermission("feature", true); assertEquals(p.getName(), "feature"); String id = permissionManager.resolveResourceId(p); assertNull(id); } @Test public void testCheckPermission1() { User user = createUserMock("viewAll"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission2() { User user = createUserMock("viewAll", "onlyView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission3() { User user = createUserMock("viewAll", "onlyView1", "noView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission4() { User user = createUserMock("viewAll", "noView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission5() { User user = createUserMock("onlyView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission6() { User user = createUserMock("noView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_ABSTAIN); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_ABSTAIN); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_GRANTED); } @Test public void testCheckPermission7() { User user = createUserMock("onlyView1", "noView1"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_DENIED); } @Test public void testCheckPermission8() { User user = createUserMock("noView1", "onlyView12"); assertEquals(permissionManager.checkPermission(viewAll, user), ACCESS_ABSTAIN); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_DENIED); assertEquals(permissionManager.checkPermission(view2, user), ACCESS_ABSTAIN); assertEquals(permissionManager.checkPermission(view12, user), ACCESS_GRANTED); assertEquals(permissionManager.checkPermission(noView1, user), ACCESS_GRANTED); } @Test public void testCacheHits() { User user = createUserMock("viewAll"); permissionManager.checkPermission(viewAll, user); permissionManager.checkPermission(viewAll, user); permissionManager.checkPermission(viewAll, user); permissionManager.checkPermission(viewAll, user); verify(permissionManager, times(1)).resolvePermissions(user, VotingStrategy.PRIORITY); verify(authzResultCache, times(1)).put(user, viewAll, AuthorizationResult.ACCESS_GRANTED); verify(authzResultCache, times(4)).get(user, viewAll); assertEquals(authzResultCache.size(user), 1); assertEquals(authzResultCache.size(createUserMock()), 0); } @Test public void testDefaultVotingStrategy() { User user = createUserMock("role1"); assertEquals(permissionManager.getDefaultVotingStrategy(), VotingStrategy.PRIORITY); VotingAlgorithm unanimousVoter = mock(VotingAlgorithm.class); when(unanimousVoter.vote(any())).thenReturn(AuthorizationResult.ACCESS_GRANTED); permissionManager.setDefaultVotingStrategy(VotingStrategy.UNANIMOUS); permissionManager.setVotingAlgorithm(VotingStrategy.UNANIMOUS, unanimousVoter); permissionManager.checkPermission(viewAll, user); verify(unanimousVoter).vote(any()); permissionManager.checkPermission(viewAll, user, null); verify(unanimousVoter).vote(any()); VotingAlgorithm affirmativeVoter = mock(VotingAlgorithm.class); when(affirmativeVoter.vote(any())).thenReturn(AuthorizationResult.ACCESS_GRANTED); authzResultCache.clear(); permissionManager.setDefaultVotingStrategy(VotingStrategy.AFFIRMATIVE); permissionManager.setVotingAlgorithm(VotingStrategy.AFFIRMATIVE, affirmativeVoter); permissionManager.checkPermission(viewAll, user); verify(affirmativeVoter).vote(any()); VotingAlgorithm consensusVoter = mock(VotingAlgorithm.class); when(consensusVoter.vote(any())).thenReturn(AuthorizationResult.ACCESS_GRANTED); authzResultCache.clear(); permissionManager.setDefaultVotingStrategy(VotingStrategy.CONSENSUS); permissionManager.setVotingAlgorithm(VotingStrategy.CONSENSUS, consensusVoter); permissionManager.checkPermission(viewAll, user); verify(consensusVoter).vote(any()); } @Test public void testPriorityVoting1() { User user = createUserMock("role1", "role2", "role3"); AuthorizationPolicy policy = permissionManager.newAuthorizationPolicy() .role("role1", 1).permission("resource.read", true) .role("role2", 2).permission("resource.read", false) .role("role3", 3).permission("resource.read.1", true) .build(); permissionManager.setAuthorizationPolicy(policy); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); PermissionCollection pc = permissionManager.resolvePermissions(user, VotingStrategy.PRIORITY); Collection<Permission> permissions = pc.collection(); assertEquals(permissions.size(), 2); assertTrue(permissions.contains(denyAll)); assertTrue(permissions.contains(view1)); } @Test public void testPriorityVoting2() { User user = createUserMock("role1", "role2", "role3"); AuthorizationPolicy policy = permissionManager.newAuthorizationPolicy() .role("role1", 3).permission("resource.read", true) .role("role2", 2).permission("resource.read", false) .role("role3", 1).permission("resource.read.1", true) .build(); permissionManager.setAuthorizationPolicy(policy); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_GRANTED); PermissionCollection pc = permissionManager.resolvePermissions(user, VotingStrategy.PRIORITY); Collection<Permission> permissions = pc.collection(); assertEquals(permissions.size(), 1); assertTrue(permissions.contains(viewAll)); } @Test public void testPriorityVoting3() { User user = createUserMock("role1", "role2", "role3"); AuthorizationPolicy policy = permissionManager.newAuthorizationPolicy() .role("role1", 1).permission("resource.read", true) .role("role2", 2).permission("resource.read", false) .role("role3", 1).permission("resource.read.1", true) .build(); permissionManager.setAuthorizationPolicy(policy); assertEquals(permissionManager.checkPermission(view1, user), ACCESS_DENIED); PermissionCollection pc = permissionManager.resolvePermissions(user, VotingStrategy.PRIORITY); Collection<Permission> permissions = pc.collection(); assertEquals(permissions.size(), 1); assertTrue(permissions.contains(denyAll)); } @Test public void testUnanimousVoting() { permissionManager.setAuthorizationPolicy(permissionManager.newAuthorizationPolicy() .role("role1").permission("resource.read", true) .role("role2").permission("resource.read", false) .role("role3").permission("resource.read", true) .build()); User user = createUserMock("role1", "role2", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.UNANIMOUS), ACCESS_DENIED); user = createUserMock("role1", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.UNANIMOUS), ACCESS_GRANTED); } @Test public void testConsensusVoting() { permissionManager.setAuthorizationPolicy(permissionManager.newAuthorizationPolicy() .role("role1").permission("resource.read", true) .role("role2").permission("resource.read", false) .role("role3").permission("resource.read", true) .build()); User user = createUserMock("role1", "role2", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.CONSENSUS), ACCESS_DENIED); user = createUserMock("role1", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.CONSENSUS), ACCESS_GRANTED); } @Test public void testAffirmativeVoting() { permissionManager.setAuthorizationPolicy(permissionManager.newAuthorizationPolicy() .role("role1").permission("resource.read", true) .role("role2").permission("resource.read", false) .role("role3").permission("resource.read", true) .build()); User user = createUserMock("role1", "role2", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.AFFIRMATIVE), ACCESS_GRANTED); user = createUserMock("role1", "role3"); assertEquals(permissionManager.checkPermission(viewAll, user, VotingStrategy.AFFIRMATIVE), ACCESS_GRANTED); } }