diff --git a/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java index 3e7986eaf6..ad63fcd730 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java @@ -31,19 +31,35 @@ package sonia.scm.security; +import com.github.sdorra.shiro.ShiroRule; +import com.github.sdorra.shiro.SubjectAware; +import com.google.common.base.Predicate; +import com.google.common.collect.Lists; +import org.apache.shiro.authz.AuthorizationInfo; +import org.apache.shiro.authz.Permission; +import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.authz.permission.PermissionResolver; +import org.apache.shiro.authz.permission.WildcardPermission; +import org.apache.shiro.subject.SimplePrincipalCollection; +import org.apache.shiro.subject.Subject; +import org.hamcrest.Matchers; import org.junit.Test; import org.junit.Before; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import static org.mockito.Mockito.*; +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; +import org.junit.Rule; import org.mockito.runners.MockitoJUnitRunner; import sonia.scm.HandlerEvent; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; import sonia.scm.group.Group; import sonia.scm.group.GroupEvent; +import sonia.scm.group.GroupNames; +import sonia.scm.repository.PermissionType; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryEvent; @@ -77,6 +93,9 @@ public class AuthorizationCollectorTest { private AuthorizationCollector collector; + @Rule + public ShiroRule shiro = new ShiroRule(); + /** * Set up object to test. */ @@ -143,5 +162,152 @@ public class AuthorizationCollectorTest { collector.onEvent(new StoredAssignedPermissionEvent(HandlerEvent.CREATE, permission)); verify(cache).clear(); } + + /** + * Tests {@link AuthorizationCollector#collect()} without user role. + */ + @Test + @SubjectAware + public void testCollectWithoutUserRole() + { + AuthorizationInfo authInfo = collector.collect(); + assertThat(authInfo.getRoles(), nullValue()); + assertThat(authInfo.getStringPermissions(), nullValue()); + assertThat(authInfo.getObjectPermissions(), nullValue()); + } + + /** + * Tests {@link AuthorizationCollector#collect()} from cache. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectFromCache() + { + AuthorizationInfo info = new SimpleAuthorizationInfo(); + when(cache.get(anyObject())).thenReturn(info); + authenticate(UserTestData.createTrillian(), "main"); + + AuthorizationInfo authInfo = collector.collect(); + assertSame(info, authInfo); + } + + /** + * Tests {@link AuthorizationCollector#collect()} with cache. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectWithCache(){ + authenticate(UserTestData.createTrillian(), "main"); + + AuthorizationInfo authInfo = collector.collect(); + verify(cache).put(any(), any()); + } + + /** + * Tests {@link AuthorizationCollector#collect()} without permissions. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectWithoutPermissions() + { + authenticate(UserTestData.createTrillian(), "main"); + + AuthorizationInfo authInfo = collector.collect(); + assertThat(authInfo.getRoles(), Matchers.contains(Role.USER)); + assertThat(authInfo.getStringPermissions(), nullValue()); + assertThat(authInfo.getObjectPermissions(), hasSize(0)); + } + + /** + * Tests {@link AuthorizationCollector#collect()} as admin. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectAsAdmin() + { + User trillian = UserTestData.createTrillian(); + trillian.setAdmin(true); + authenticate(trillian, "main"); + + AuthorizationInfo authInfo = collector.collect(); + assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER, Role.ADMIN)); + assertThat(authInfo.getStringPermissions(), nullValue()); + Permission permission = new RepositoryPermission(RepositoryPermission.WILDCARD, PermissionType.OWNER); + assertThat(authInfo.getObjectPermissions(), contains(permission)); + } + + /** + * Tests {@link AuthorizationCollector#collect()} with repository permissions. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectWithRepositoryPermissions() + { + String group = "heart-of-gold-crew"; + authenticate(UserTestData.createTrillian(), group); + Repository heartOfGold = RepositoryTestData.createHeartOfGold(); + heartOfGold.setId("one"); + heartOfGold.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("trillian"))); + Repository puzzle42 = RepositoryTestData.create42Puzzle(); + puzzle42.setId("two"); + sonia.scm.repository.Permission permission = new sonia.scm.repository.Permission(group, PermissionType.WRITE, true); + puzzle42.setPermissions(Lists.newArrayList(permission)); + when(repositoryDAO.getAll()).thenReturn(Lists.newArrayList(heartOfGold, puzzle42)); + + // execute and assert + AuthorizationInfo authInfo = collector.collect(); + assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); + assertThat(authInfo.getStringPermissions(), nullValue()); + Permission p1 = new RepositoryPermission("one", PermissionType.READ); + Permission p2 = new RepositoryPermission("two", PermissionType.WRITE); + assertThat(authInfo.getObjectPermissions(), containsInAnyOrder(p1, p2)); + } + + /** + * Tests {@link AuthorizationCollector#collect()} with global permissions. + */ + @Test + @SubjectAware( + configuration = "classpath:sonia/scm/shiro-001.ini" + ) + public void testCollectWithGlobalPermissions(){ + authenticate(UserTestData.createTrillian(), "main"); + + StoredAssignedPermission p1 = new StoredAssignedPermission("one", new AssignedPermission("one", "one:one")); + StoredAssignedPermission p2 = new StoredAssignedPermission("two", new AssignedPermission("two", "two:two")); + when(securitySystem.getPermissions(Mockito.any(Predicate.class))).thenReturn(Lists.newArrayList(p1, p2)); + + Permission wp1 = new WildcardPermission("one"); + when(resolver.resolvePermission("one:one")).thenReturn(wp1); + Permission wp2 = new WildcardPermission("two"); + when(resolver.resolvePermission("two:two")).thenReturn(wp2); + + // execute and assert + AuthorizationInfo authInfo = collector.collect(); + assertThat(authInfo.getRoles(), Matchers.containsInAnyOrder(Role.USER)); + assertThat(authInfo.getStringPermissions(), nullValue()); + + assertThat(authInfo.getObjectPermissions(), containsInAnyOrder(wp1, wp2)); + } + + private void authenticate(User user, String group, String... groups) + { + SimplePrincipalCollection spc = new SimplePrincipalCollection(); + spc.add(user.getName(), "unit"); + spc.add(user, "unit"); + spc.add(new GroupNames(group, groups), "unit"); + Subject subject = new Subject.Builder().authenticated(true).principals(spc).buildSubject(); + shiro.setSubject(subject); + } } \ No newline at end of file