From 4a9d14b7080460ffb327119ce057390fd08b3e03 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 30 Aug 2012 13:20:26 +0200 Subject: [PATCH] mark security context as deprecated and use shiro apis instead --- .../sonia/scm/client/it/ClientTestUtil.java | 3 +- .../sonia/scm/security/SecurityContext.java | 2 + .../java/sonia/scm/util/SecurityUtil.java | 53 ++++++++++----- .../scm/web/security/WebSecurityContext.java | 3 + .../sonia/scm/user/UserManagerTestBase.java | 14 ++-- .../main/java/sonia/scm/util/MockUtil.java | 15 +++++ .../resources/ChangePasswordResource.java | 29 ++++---- .../rest/resources/ConfigurationResource.java | 30 +++++---- .../scm/api/rest/resources/GroupResource.java | 24 +++---- .../resources/RepositoryImportResource.java | 21 ++---- .../rest/resources/RepositoryResource.java | 16 ++--- .../api/rest/resources/SearchResource.java | 18 ++--- .../api/rest/resources/SupportResource.java | 25 ++++--- .../scm/api/rest/resources/UserResource.java | 21 +++--- .../sonia/scm/filter/AdminSecurityFilter.java | 28 ++------ .../java/sonia/scm/filter/SecurityFilter.java | 67 ++++++------------- .../sonia/scm/group/DefaultGroupManager.java | 20 ++---- .../scm/plugin/DefaultPluginManager.java | 49 ++++++-------- .../java/sonia/scm/search/SearchHandler.java | 26 +++---- .../sonia/scm/user/DefaultUserManager.java | 53 +++++++++------ .../ApiBasicAuthenticationFilter.java | 30 ++------- .../sonia/scm/web/security/SecurityUtil.java | 2 + .../scm/user/DefaultUserManagerTest.java | 11 ++- .../DefaultAuthenticationHandlerTest.java | 15 +++-- 24 files changed, 277 insertions(+), 298 deletions(-) diff --git a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java index b2efca3439..a9caf9d50e 100644 --- a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java +++ b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java @@ -38,7 +38,6 @@ package sonia.scm.client.it; import sonia.scm.client.ClientUtil; import sonia.scm.client.JerseyClientProvider; import sonia.scm.client.JerseyClientSession; -import sonia.scm.client.ScmUrlProvider; import sonia.scm.config.ScmConfiguration; import sonia.scm.url.UrlProvider; @@ -106,7 +105,7 @@ public class ClientTestUtil * */ public static JerseyClientSession createSession(String username, - String password) + String password) { JerseyClientProvider provider = new JerseyClientProvider(REQUEST_LOGGING); diff --git a/scm-core/src/main/java/sonia/scm/security/SecurityContext.java b/scm-core/src/main/java/sonia/scm/security/SecurityContext.java index 226a247d4a..34baca2f5e 100644 --- a/scm-core/src/main/java/sonia/scm/security/SecurityContext.java +++ b/scm-core/src/main/java/sonia/scm/security/SecurityContext.java @@ -40,7 +40,9 @@ import sonia.scm.user.User; /** * * @author Sebastian Sdorra + * @deprecated use {@link SecurityUtils#getSecurityManager()} instead. */ +@Deprecated public interface SecurityContext { diff --git a/scm-core/src/main/java/sonia/scm/util/SecurityUtil.java b/scm-core/src/main/java/sonia/scm/util/SecurityUtil.java index 1bf585ddf9..d8bf4c40d7 100644 --- a/scm-core/src/main/java/sonia/scm/util/SecurityUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/SecurityUtil.java @@ -37,7 +37,11 @@ package sonia.scm.util; import com.google.inject.Provider; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + import sonia.scm.SCMContext; +import sonia.scm.security.Role; import sonia.scm.security.ScmSecurityException; import sonia.scm.security.SecurityContext; import sonia.scm.user.User; @@ -54,36 +58,51 @@ public class SecurityUtil * * * @param contextProvider + * @deprecated use {@link Subject#checkRole(java.lang.String)} with { + * @link Role#ADMIN} instead. */ + @Deprecated public static void assertIsAdmin( - Provider contextProvider) + Provider contextProvider) { - assertIsAdmin(contextProvider.get()); + assertIsAdmin(); } /** - * Method description + * This method is only present for compatibility reasons. + * Use {@link Subject#checkRole(java.lang.String)} with { + * @link Role#ADMIN} instead. * - * - * @param context + * @since 1.21 */ - public static void assertIsAdmin(SecurityContext context) + public static void assertIsAdmin() { - AssertUtil.assertIsNotNull(context); + Subject subject = SecurityUtils.getSubject(); - User user = context.getUser(); - - if (user == null) + if (!subject.isAuthenticated()) { throw new ScmSecurityException("user is not authenticated"); } - - if (!user.isAdmin()) + else if (!subject.hasRole(Role.ADMIN)) { throw new ScmSecurityException("admin account is required"); } } + /** + * Method description + * + * + * @param context + * @deprecated use {@link Subject#checkRole(java.lang.String)} with { + * @link Role#ADMIN} instead. + */ + @Deprecated + public static void assertIsAdmin(SecurityContext context) + { + assertIsAdmin(); + } + /** * Method description * @@ -91,7 +110,7 @@ public class SecurityUtil * @param contextProvider */ public static void assertIsNotAnonymous( - Provider contextProvider) + Provider contextProvider) { if (isAnonymous(contextProvider)) { @@ -124,7 +143,7 @@ public class SecurityUtil * @return */ public static User getCurrentUser( - Provider contextProvider) + Provider contextProvider) { AssertUtil.assertIsNotNull(contextProvider); @@ -151,7 +170,7 @@ public class SecurityUtil * @return */ public static boolean isAdmin( - Provider contextProvider) + Provider contextProvider) { return isAdmin(contextProvider.get()); } @@ -169,7 +188,7 @@ public class SecurityUtil AssertUtil.assertIsNotNull(contextProvider); return (contextProvider.getUser() != null) - && contextProvider.getUser().isAdmin(); + && contextProvider.getUser().isAdmin(); } /** @@ -181,7 +200,7 @@ public class SecurityUtil * @return */ public static boolean isAnonymous( - Provider contextProvider) + Provider contextProvider) { return isAnonymous(contextProvider.get()); } diff --git a/scm-core/src/main/java/sonia/scm/web/security/WebSecurityContext.java b/scm-core/src/main/java/sonia/scm/web/security/WebSecurityContext.java index 1b9ccec280..d99716a5ff 100644 --- a/scm-core/src/main/java/sonia/scm/web/security/WebSecurityContext.java +++ b/scm-core/src/main/java/sonia/scm/web/security/WebSecurityContext.java @@ -44,11 +44,14 @@ import java.util.Collection; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.shiro.SecurityUtils; /** * * @author Sebastian Sdorra + * @deprecated use {@link SecurityUtils#getSecurityManager()} instead. */ +@Deprecated public interface WebSecurityContext extends SecurityContext { diff --git a/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java b/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java index f3594e2987..2841eafe72 100644 --- a/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java +++ b/scm-test/src/main/java/sonia/scm/user/UserManagerTestBase.java @@ -35,6 +35,9 @@ package sonia.scm.user; //~--- non-JDK imports -------------------------------------------------------- +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + import org.junit.Test; import sonia.scm.Manager; @@ -56,7 +59,7 @@ import java.util.UUID; * @author Sebastian Sdorra */ public abstract class UserManagerTestBase - extends ManagerTestBase + extends ManagerTestBase { /** Field description */ @@ -265,7 +268,7 @@ public abstract class UserManagerTestBase */ @Test public void testMultiThreaded() - throws UserException, IOException, InterruptedException + throws UserException, IOException, InterruptedException { int initialSize = manager.getAll().size(); List testers = new ArrayList(); @@ -275,8 +278,11 @@ public abstract class UserManagerTestBase testers.add(new MultiThreadTester(manager)); } + Subject subject = SecurityUtils.getSubject(); + for (MultiThreadTester tester : testers) { + subject.associateWith(tester); new Thread(tester).start(); } @@ -393,7 +399,7 @@ public abstract class UserManagerTestBase { String id = UUID.randomUUID().toString(); User user = new User(id, id.concat(" displayName"), - id.concat("@mail.com")); + id.concat("@mail.com")); manager.create(user); @@ -410,7 +416,7 @@ public abstract class UserManagerTestBase * @throws UserException */ private void modifyAndDeleteUser(User user) - throws UserException, IOException + throws UserException, IOException { String name = user.getName(); String nd = name.concat(" new displayname"); diff --git a/scm-test/src/main/java/sonia/scm/util/MockUtil.java b/scm-test/src/main/java/sonia/scm/util/MockUtil.java index 14a049e552..bb6a0a1ca8 100644 --- a/scm-test/src/main/java/sonia/scm/util/MockUtil.java +++ b/scm-test/src/main/java/sonia/scm/util/MockUtil.java @@ -38,6 +38,7 @@ package sonia.scm.util; import com.google.inject.Provider; import org.apache.shiro.authz.Permission; +import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; import org.mockito.invocation.InvocationOnMock; @@ -67,6 +68,12 @@ import javax.servlet.http.HttpServletResponse; public class MockUtil { + /** Field description */ + private static final User ADMIN = new User("scmadmin", "SCM Admin", + "scmadmin@scm.org"); + + //~--- methods -------------------------------------------------------------- + /** * Method description * @@ -101,6 +108,14 @@ public class MockUtil when(subject.isPermittedAll()).thenReturn(Boolean.TRUE); when(subject.hasRole("admin")).thenReturn(Boolean.TRUE); + PrincipalCollection collection = mock(PrincipalCollection.class); + + when(collection.getPrimaryPrincipal()).thenReturn(ADMIN.getId()); + when(collection.oneByType(User.class)).thenReturn(ADMIN); + + when(subject.getPrincipal()).thenReturn(ADMIN.getId()); + when(subject.getPrincipals()).thenReturn(collection); + return subject; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java index 9b4b05c43e..48c63b3b0a 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java @@ -36,7 +36,9 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; -import com.google.inject.Provider; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; import org.codehaus.enunciate.jaxrs.TypeHint; import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; @@ -46,11 +48,11 @@ import org.slf4j.LoggerFactory; import sonia.scm.api.rest.RestActionResult; import sonia.scm.security.EncryptionHandler; +import sonia.scm.security.ScmSecurityException; import sonia.scm.user.User; import sonia.scm.user.UserException; import sonia.scm.user.UserManager; import sonia.scm.util.AssertUtil; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -88,13 +90,11 @@ public class ChangePasswordResource * @param securityContextProvider */ @Inject - public ChangePasswordResource( - UserManager userManager, EncryptionHandler encryptionHandler, - Provider securityContextProvider) + public ChangePasswordResource(UserManager userManager, + EncryptionHandler encryptionHandler) { this.userManager = userManager; this.encryptionHandler = encryptionHandler; - this.securityContextProvider = securityContextProvider; } //~--- methods -------------------------------------------------------------- @@ -121,8 +121,8 @@ public class ChangePasswordResource @TypeHint(RestActionResult.class) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response changePassword(@FormParam("old-password") String oldPassword, - @FormParam("new-password") String newPassword) - throws UserException, IOException + @FormParam("new-password") String newPassword) + throws UserException, IOException { AssertUtil.assertIsNotEmpty(oldPassword); AssertUtil.assertIsNotEmpty(newPassword); @@ -135,8 +135,14 @@ public class ChangePasswordResource } Response response = null; - WebSecurityContext securityContext = securityContextProvider.get(); - User currentUser = securityContext.getUser(); + Subject subject = SecurityUtils.getSubject(); + + if (!subject.isAuthenticated()) + { + throw new ScmSecurityException("user is not authenticated"); + } + + User currentUser = subject.getPrincipals().oneByType(User.class); if (logger.isInfoEnabled()) { @@ -178,9 +184,6 @@ public class ChangePasswordResource /** Field description */ private EncryptionHandler encryptionHandler; - /** Field description */ - private Provider securityContextProvider; - /** Field description */ private UserManager userManager; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java index 36cd0d149a..6c888470ad 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java @@ -36,15 +36,17 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; import sonia.scm.config.ScmConfiguration; +import sonia.scm.security.Role; +import sonia.scm.security.ScmSecurityException; import sonia.scm.util.ScmConfigurationUtil; -import sonia.scm.util.SecurityUtil; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -76,11 +78,8 @@ public class ConfigurationResource * @param securityContextProvider */ @Inject - public ConfigurationResource( - Provider securityContextProvider, - ScmConfiguration configuration) + public ConfigurationResource(ScmConfiguration configuration) { - this.securityContextProvider = securityContextProvider; this.configuration = configuration; } @@ -98,7 +97,7 @@ public class ConfigurationResource { Response response = null; - if (SecurityUtil.isAdmin(securityContextProvider)) + if (SecurityUtils.getSubject().hasRole(Role.ADMIN)) { response = Response.ok(configuration).build(); } @@ -124,9 +123,17 @@ public class ConfigurationResource @POST @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public Response setConfig(@Context UriInfo uriInfo, - ScmConfiguration newConfig) + ScmConfiguration newConfig) { - SecurityUtil.assertIsAdmin(securityContextProvider); + + // TODO replace by checkRole + Subject subject = SecurityUtils.getSubject(); + + if (!subject.hasRole(Role.ADMIN)) + { + throw new ScmSecurityException("admin privileges required"); + } + configuration.load(newConfig); synchronized (ScmConfiguration.class) @@ -141,7 +148,4 @@ public class ConfigurationResource /** Field description */ public ScmConfiguration configuration; - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java index f542195bf4..f1a4d19ff3 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java @@ -39,14 +39,15 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; + import org.codehaus.enunciate.jaxrs.TypeHint; import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; import sonia.scm.group.Group; import sonia.scm.group.GroupException; import sonia.scm.group.GroupManager; -import sonia.scm.util.SecurityUtil; -import sonia.scm.web.security.WebSecurityContext; +import sonia.scm.security.Role; //~--- JDK imports ------------------------------------------------------------ @@ -77,7 +78,7 @@ import javax.ws.rs.core.UriInfo; @Singleton @ExternallyManagedLifecycle public class GroupResource - extends AbstractManagerResource + extends AbstractManagerResource { /** Field description */ @@ -94,11 +95,9 @@ public class GroupResource * @param groupManager */ @Inject - public GroupResource(Provider securityContextProvider, - GroupManager groupManager) + public GroupResource(GroupManager groupManager) { super(groupManager); - this.securityContextProvider = securityContextProvider; } //~--- methods -------------------------------------------------------------- @@ -172,7 +171,7 @@ public class GroupResource @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response update(@Context UriInfo uriInfo, - @PathParam("id") String name, Group group) + @PathParam("id") String name, Group group) { return super.update(uriInfo, name, group); } @@ -205,7 +204,7 @@ public class GroupResource { Response response = null; - if (SecurityUtil.isAdmin(securityContextProvider)) + if (SecurityUtils.getSubject().hasRole(Role.ADMIN)) { response = super.get(request, id); } @@ -243,7 +242,7 @@ public class GroupResource public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("start") int start, @DefaultValue("-1") @QueryParam("limit") int limit, @QueryParam("sortby") String sortby, - @DefaultValue("false") + @DefaultValue("false") @QueryParam("desc") boolean desc) { return super.getAll(request, start, limit, sortby, desc); @@ -261,7 +260,7 @@ public class GroupResource */ @Override protected GenericEntity> createGenericEntity( - Collection items) + Collection items) { return new GenericEntity>(items) {} ; @@ -294,9 +293,4 @@ public class GroupResource { return PATH_PART; } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 4462f28c2d..b3a994112a 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -30,12 +30,12 @@ */ + package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; import org.codehaus.enunciate.jaxrs.TypeHint; @@ -50,7 +50,6 @@ import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryManager; import sonia.scm.util.SecurityUtil; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -93,12 +92,9 @@ public class RepositoryImportResource * @param securityContextProvider */ @Inject - public RepositoryImportResource( - RepositoryManager manager, - Provider securityContextProvider) + public RepositoryImportResource(RepositoryManager manager) { this.manager = manager; - this.securityContextProvider = securityContextProvider; } //~--- methods -------------------------------------------------------------- @@ -116,9 +112,9 @@ public class RepositoryImportResource @TypeHint(Repository[].class) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public GenericEntity> importRepositories( - @PathParam("type") String type) + @PathParam("type") String type) { - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); List repositories = new ArrayList(); RepositoryHandler handler = manager.getHandler(type); @@ -143,7 +139,7 @@ public class RepositoryImportResource else if (logger.isWarnEnabled()) { logger.warn("could not find imported repository {}", - repositoryName); + repositoryName); } } } @@ -175,7 +171,7 @@ public class RepositoryImportResource @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public GenericEntity> getImportableTypes() { - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); List types = new ArrayList(); Collection handlerTypes = manager.getTypes(); @@ -202,7 +198,7 @@ public class RepositoryImportResource else if (logger.isInfoEnabled()) { logger.info("{} handler does not support import of repositories", - t.getName()); + t.getName()); } } } @@ -220,7 +216,4 @@ public class RepositoryImportResource /** Field description */ private RepositoryManager manager; - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index a8adf22f6e..7801abf7b2 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -38,9 +38,10 @@ package sonia.scm.api.rest.resources; import com.google.common.base.Strings; import com.google.common.io.Closeables; import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; + import org.codehaus.enunciate.jaxrs.TypeHint; import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; @@ -55,7 +56,6 @@ import sonia.scm.repository.Changeset; import sonia.scm.repository.ChangesetPagingResult; import sonia.scm.repository.Permission; import sonia.scm.repository.PermissionType; -import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryIsNotArchivedException; @@ -71,10 +71,10 @@ import sonia.scm.repository.api.DiffCommandBuilder; import sonia.scm.repository.api.LogCommandBuilder; import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryServiceFactory; +import sonia.scm.security.RepositoryPermission; import sonia.scm.security.ScmSecurityException; import sonia.scm.util.AssertUtil; import sonia.scm.util.Util; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -137,14 +137,12 @@ public class RepositoryResource @Inject public RepositoryResource(ScmConfiguration configuration, RepositoryManager repositoryManager, - Provider securityContextProvider, RepositoryServiceFactory servicefactory) { super(repositoryManager); this.configuration = configuration; this.repositoryManager = repositoryManager; this.servicefactory = servicefactory; - this.securityContextProvider = securityContextProvider; setDisableCache(false); } @@ -1091,8 +1089,9 @@ public class RepositoryResource */ private boolean isOwner(Repository repository) { - return PermissionUtil.hasPermission(repository, securityContextProvider, - PermissionType.OWNER); + + return SecurityUtils.getSubject().isPermitted( + new RepositoryPermission(repository, PermissionType.OWNER)); } //~--- fields --------------------------------------------------------------- @@ -1103,9 +1102,6 @@ public class RepositoryResource /** Field description */ private RepositoryManager repositoryManager; - /** Field description */ - private Provider securityContextProvider; - /** Field description */ private RepositoryServiceFactory servicefactory; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java index e636b60852..0b01dffeaa 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SearchResource.java @@ -37,7 +37,6 @@ package sonia.scm.api.rest.resources; import com.google.common.base.Function; import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; @@ -54,7 +53,6 @@ import sonia.scm.search.SearchResults; import sonia.scm.user.User; import sonia.scm.user.UserListener; import sonia.scm.user.UserManager; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -92,9 +90,8 @@ public class SearchResource implements UserListener, GroupListener * @param cacheManager */ @Inject - public SearchResource(Provider securityContextProvider, - UserManager userManager, GroupManager groupManager, - CacheManager cacheManager) + public SearchResource(UserManager userManager, GroupManager groupManager, + CacheManager cacheManager) { // create user searchhandler @@ -103,8 +100,7 @@ public class SearchResource implements UserListener, GroupListener Cache userCache = cacheManager.getCache(String.class, SearchResults.class, CACHE_USER); - this.userSearchHandler = new SearchHandler(securityContextProvider, - userCache, userManager); + this.userSearchHandler = new SearchHandler(userCache, userManager); // create group searchhandler groupManager.addListener(this); @@ -112,8 +108,8 @@ public class SearchResource implements UserListener, GroupListener Cache groupCache = cacheManager.getCache(String.class, SearchResults.class, CACHE_GROUP); - this.groupSearchHandler = new SearchHandler(securityContextProvider, - groupCache, groupManager); + this.groupSearchHandler = new SearchHandler(groupCache, + groupManager); } //~--- methods -------------------------------------------------------------- @@ -162,7 +158,7 @@ public class SearchResource implements UserListener, GroupListener public SearchResults searchGroups(@QueryParam("query") String queryString) { return groupSearchHandler.search(queryString, - new Function() + new Function() { @Override public SearchResult apply(Group group) @@ -198,7 +194,7 @@ public class SearchResource implements UserListener, GroupListener public SearchResults searchUsers(@QueryParam("query") String queryString) { return userSearchHandler.search(queryString, - new Function() + new Function() { @Override public SearchResult apply(User user) diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java index 2472f81436..06f65c44d5 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/SupportResource.java @@ -39,6 +39,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.inject.Inject; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; import sonia.scm.SCMContextProvider; @@ -47,10 +50,10 @@ import sonia.scm.config.ScmConfiguration; import sonia.scm.plugin.PluginManager; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryManager; +import sonia.scm.security.Role; +import sonia.scm.security.ScmSecurityException; import sonia.scm.store.StoreFactory; -import sonia.scm.util.SecurityUtil; import sonia.scm.util.SystemUtil; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -96,12 +99,10 @@ public class SupportResource * @param repositoryManager */ @Inject - public SupportResource(WebSecurityContext securityContext, - SCMContextProvider context, ScmConfiguration configuration, - PluginManager pluginManager, StoreFactory storeFactory, - RepositoryManager repositoryManager) + public SupportResource(SCMContextProvider context, + ScmConfiguration configuration, PluginManager pluginManager, + StoreFactory storeFactory, RepositoryManager repositoryManager) { - this.securityContext = securityContext; this.context = context; this.configuration = configuration; this.pluginManager = pluginManager; @@ -123,7 +124,12 @@ public class SupportResource @Produces(MediaType.TEXT_HTML) public Viewable getSupport() throws IOException { - SecurityUtil.assertIsAdmin(securityContext); + Subject subject = SecurityUtils.getSubject(); + + if (!subject.hasRole(Role.ADMIN)) + { + throw new ScmSecurityException("admin privileges required"); + } Map env = Maps.newHashMap(); @@ -445,9 +451,6 @@ public class SupportResource /** Field description */ private RepositoryManager repositoryManager; - /** Field description */ - private WebSecurityContext securityContext; - /** Field description */ private Class storeFactoryClass; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java index 62deb10607..ad264fd0a8 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/UserResource.java @@ -36,20 +36,20 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; + import org.codehaus.enunciate.jaxrs.TypeHint; import org.codehaus.enunciate.modules.jersey.ExternallyManagedLifecycle; import sonia.scm.security.EncryptionHandler; +import sonia.scm.security.Role; import sonia.scm.user.User; import sonia.scm.user.UserException; import sonia.scm.user.UserManager; import sonia.scm.util.AssertUtil; -import sonia.scm.util.SecurityUtil; import sonia.scm.util.Util; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -100,12 +100,10 @@ public class UserResource extends AbstractManagerResource */ @Inject public UserResource(UserManager userManager, - EncryptionHandler encryptionHandler, - Provider securityContextProvider) + EncryptionHandler encryptionHandler) { super(userManager); this.encryptionHandler = encryptionHandler; - this.securityContextProvider = securityContextProvider; } //~--- methods -------------------------------------------------------------- @@ -179,7 +177,7 @@ public class UserResource extends AbstractManagerResource @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Override public Response update(@Context UriInfo uriInfo, - @PathParam("id") String name, User user) + @PathParam("id") String name, User user) { return super.update(uriInfo, name, user); } @@ -212,7 +210,7 @@ public class UserResource extends AbstractManagerResource { Response response = null; - if (SecurityUtil.isAdmin(securityContextProvider)) + if (SecurityUtils.getSubject().hasRole(Role.ADMIN)) { response = super.get(request, id); } @@ -250,7 +248,7 @@ public class UserResource extends AbstractManagerResource public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("start") int start, @DefaultValue("-1") @QueryParam("limit") int limit, @QueryParam("sortby") String sortby, - @DefaultValue("false") + @DefaultValue("false") @QueryParam("desc") boolean desc) { return super.getAll(request, start, limit, sortby, desc); @@ -268,7 +266,7 @@ public class UserResource extends AbstractManagerResource */ @Override protected GenericEntity> createGenericEntity( - Collection items) + Collection items) { return new GenericEntity>(items) {} ; @@ -396,7 +394,4 @@ public class UserResource extends AbstractManagerResource /** Field description */ private EncryptionHandler encryptionHandler; - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/filter/AdminSecurityFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/AdminSecurityFilter.java index 272803d0b2..657bf134d9 100644 --- a/scm-webapp/src/main/java/sonia/scm/filter/AdminSecurityFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/filter/AdminSecurityFilter.java @@ -35,12 +35,11 @@ package sonia.scm.filter; //~--- non-JDK imports -------------------------------------------------------- -import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; -import sonia.scm.util.SecurityUtil; -import sonia.scm.web.security.WebSecurityContext; +import org.apache.shiro.subject.Subject; + +import sonia.scm.security.Role; /** * @@ -50,32 +49,19 @@ import sonia.scm.web.security.WebSecurityContext; public class AdminSecurityFilter extends SecurityFilter { - /** - * Constructs ... - * - * - * @param securityContextProvider - */ - @Inject - public AdminSecurityFilter( - Provider securityContextProvider) - { - super(securityContextProvider); - } - - //~--- get methods ---------------------------------------------------------- - /** * Method description * * * @param securityContext * + * @param subject + * * @return */ @Override - protected boolean hasPermission(WebSecurityContext securityContext) + protected boolean hasPermission(Subject subject) { - return SecurityUtil.isAdmin(securityContext); + return subject.hasRole(Role.ADMIN); } } diff --git a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java index a276e5920e..dd1a273fd7 100644 --- a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java @@ -35,13 +35,14 @@ package sonia.scm.filter; //~--- non-JDK imports -------------------------------------------------------- -import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + +import sonia.scm.user.User; import sonia.scm.web.filter.HttpFilter; import sonia.scm.web.filter.SecurityHttpServletRequestWrapper; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -63,20 +64,6 @@ public class SecurityFilter extends HttpFilter /** Field description */ public static final String URL_AUTHENTICATION = "/api/rest/authentication"; - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param securityContextProvider - */ - @Inject - public SecurityFilter(Provider securityContextProvider) - { - this.securityContextProvider = securityContextProvider; - } - //~--- methods -------------------------------------------------------------- /** @@ -92,40 +79,29 @@ public class SecurityFilter extends HttpFilter */ @Override protected void doFilter(HttpServletRequest request, - HttpServletResponse response, FilterChain chain) - throws IOException, ServletException + HttpServletResponse response, FilterChain chain) + throws IOException, ServletException { - WebSecurityContext securityContext = securityContextProvider.get(); + Subject subject = SecurityUtils.getSubject(); - if (securityContext != null) + String uri = + request.getRequestURI().substring(request.getContextPath().length()); + + if (!uri.startsWith(URL_AUTHENTICATION)) { - String uri = - request.getRequestURI().substring(request.getContextPath().length()); - - if (!uri.startsWith(URL_AUTHENTICATION)) + if (hasPermission(subject)) { - if (hasPermission(securityContext)) - { - chain.doFilter(new SecurityHttpServletRequestWrapper(request, - securityContext.getUser()), response); - } - else if (securityContext.isAuthenticated()) - { - response.sendError(HttpServletResponse.SC_FORBIDDEN); - } - else - { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - } + chain.doFilter(new SecurityHttpServletRequestWrapper(request, + subject.getPrincipals().oneByType(User.class)), response); } else { - chain.doFilter(request, response); + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } } else { - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + chain.doFilter(request, response); } } @@ -135,17 +111,12 @@ public class SecurityFilter extends HttpFilter * Method description * * - * @param securityContext + * @param subject * * @return */ - protected boolean hasPermission(WebSecurityContext securityContext) + protected boolean hasPermission(Subject subject) { - return securityContext.isAuthenticated(); + return subject.isAuthenticated(); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java index 50e0fe90a9..9cf0f39af2 100644 --- a/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java +++ b/scm-webapp/src/main/java/sonia/scm/group/DefaultGroupManager.java @@ -47,7 +47,6 @@ import sonia.scm.SCMContextProvider; import sonia.scm.TransformFilter; import sonia.scm.search.SearchRequest; import sonia.scm.search.SearchUtil; -import sonia.scm.security.SecurityContext; import sonia.scm.util.CollectionAppender; import sonia.scm.util.SecurityUtil; import sonia.scm.util.Util; @@ -87,11 +86,9 @@ public class DefaultGroupManager extends AbstractGroupManager * @param groupListenerProvider */ @Inject - public DefaultGroupManager(Provider securityContextProvider, - GroupDAO groupDAO, + public DefaultGroupManager(GroupDAO groupDAO, Provider> groupListenerProvider) { - this.securityContextProvider = securityContextProvider; this.groupDAO = groupDAO; this.groupListenerProvider = groupListenerProvider; } @@ -136,7 +133,7 @@ public class DefaultGroupManager extends AbstractGroupManager group.getType()); } - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); if (groupDAO.contains(group.getName())) { @@ -167,7 +164,7 @@ public class DefaultGroupManager extends AbstractGroupManager group.getType()); } - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); String name = group.getName(); @@ -218,7 +215,7 @@ public class DefaultGroupManager extends AbstractGroupManager group.getType()); } - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); String name = group.getName(); @@ -253,7 +250,7 @@ public class DefaultGroupManager extends AbstractGroupManager group.getType()); } - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); Group fresh = groupDAO.get(group.getName()); @@ -346,7 +343,7 @@ public class DefaultGroupManager extends AbstractGroupManager @Override public Collection getAll(Comparator comparator) { - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); List groups = new ArrayList(); @@ -378,7 +375,7 @@ public class DefaultGroupManager extends AbstractGroupManager public Collection getAll(Comparator comparator, int start, int limit) { - SecurityUtil.assertIsAdmin(securityContextProvider); + SecurityUtil.assertIsAdmin(); return Util.createSubCollection(groupDAO.getAll(), comparator, new CollectionAppender() @@ -449,7 +446,4 @@ public class DefaultGroupManager extends AbstractGroupManager /** Field description */ private Provider> groupListenerProvider; - - /** Field description */ - private Provider securityContextProvider; } diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java index 76519f70c0..ebeb41b37e 100644 --- a/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java +++ b/scm-webapp/src/main/java/sonia/scm/plugin/DefaultPluginManager.java @@ -50,7 +50,6 @@ import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; import sonia.scm.config.ScmConfiguration; import sonia.scm.net.HttpClient; -import sonia.scm.security.SecurityContext; import sonia.scm.util.AssertUtil; import sonia.scm.util.IOUtil; import sonia.scm.util.SecurityUtil; @@ -82,7 +81,7 @@ import javax.xml.bind.Unmarshaller; */ @Singleton public class DefaultPluginManager - implements PluginManager, ConfigChangedListener + implements PluginManager, ConfigChangedListener { /** Field description */ @@ -116,17 +115,14 @@ public class DefaultPluginManager * @param clientProvider */ @Inject - public DefaultPluginManager( - SCMContextProvider context, - Provider securityContextProvicer, - ScmConfiguration configuration, PluginLoader pluginLoader, - CacheManager cacheManager, Provider clientProvider) + public DefaultPluginManager(SCMContextProvider context, + ScmConfiguration configuration, PluginLoader pluginLoader, + CacheManager cacheManager, Provider clientProvider) { this.context = context; - this.securityContextProvicer = securityContextProvicer; this.configuration = configuration; this.cache = cacheManager.getCache(String.class, PluginCenter.class, - CACHE_NAME); + CACHE_NAME); this.clientProvider = clientProvider; installedPlugins = new HashMap(); @@ -191,7 +187,7 @@ public class DefaultPluginManager @Override public void install(String id) { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); PluginCenter center = getPluginCenter(); @@ -223,7 +219,7 @@ public class DefaultPluginManager @Override public void uninstall(String id) { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); Plugin plugin = installedPlugins.get(id); @@ -267,7 +263,7 @@ public class DefaultPluginManager @Override public void update(String id) { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); String[] idParts = id.split(":"); String groupId = idParts[0]; @@ -277,7 +273,7 @@ public class DefaultPluginManager for (PluginInformation info : getInstalled()) { if (groupId.equals(info.getGroupId()) - && artefactId.equals(info.getArtifactId())) + && artefactId.equals(info.getArtifactId())) { installed = info; @@ -311,7 +307,7 @@ public class DefaultPluginManager @Override public PluginInformation get(String id) { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); PluginInformation result = null; @@ -340,7 +336,7 @@ public class DefaultPluginManager public Set get(PluginFilter filter) { AssertUtil.assertIsNotNull(filter); - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); Set infoSet = new HashSet(); @@ -359,7 +355,7 @@ public class DefaultPluginManager @Override public Collection getAll() { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); Set infoSet = getInstalled(); @@ -377,7 +373,7 @@ public class DefaultPluginManager @Override public Collection getAvailable() { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); Set availablePlugins = new HashSet(); Set centerPlugins = getPluginCenter().getPlugins(); @@ -402,7 +398,7 @@ public class DefaultPluginManager @Override public Set getAvailableUpdates() { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); return get(FILTER_UPDATES); } @@ -416,7 +412,7 @@ public class DefaultPluginManager @Override public Set getInstalled() { - SecurityUtil.assertIsAdmin(securityContextProvicer); + SecurityUtil.assertIsAdmin(); Set infoSet = new LinkedHashSet(); @@ -453,7 +449,7 @@ public class DefaultPluginManager } return url.replace("{version}", context.getVersion()).replace("{os}", - os).replace("{arch}", arch); + os).replace("{arch}", arch); } /** @@ -465,7 +461,7 @@ public class DefaultPluginManager * @param filter */ private void filter(Set target, - Collection source, PluginFilter filter) + Collection source, PluginFilter filter) { for (PluginInformation info : source) { @@ -588,7 +584,7 @@ public class DefaultPluginManager if (pluginHandler == null) { pluginHandler = new AetherPluginHandler(this, - SCMContext.getContext(), configuration); + SCMContext.getContext(), configuration); } pluginHandler.setPluginRepositories(center.getRepositories()); @@ -643,7 +639,7 @@ public class DefaultPluginManager PluginInformation installed = installedPlugin.getInformation(); if (isSamePlugin(available, installed) - && (installed.getState() == PluginState.CORE)) + && (installed.getState() == PluginState.CORE)) { core = true; @@ -664,7 +660,7 @@ public class DefaultPluginManager * @return */ private boolean isNewer(PluginInformation available, - PluginInformation installed) + PluginInformation installed) { boolean result = false; PluginVersion version = PluginVersion.createVersion(available.getVersion()); @@ -689,7 +685,7 @@ public class DefaultPluginManager private boolean isSamePlugin(PluginInformation p1, PluginInformation p2) { return p1.getGroupId().equals(p2.getGroupId()) - && p1.getArtifactId().equals(p2.getArtifactId()); + && p1.getArtifactId().equals(p2.getArtifactId()); } //~--- fields --------------------------------------------------------------- @@ -712,9 +708,6 @@ public class DefaultPluginManager /** Field description */ private AetherPluginHandler pluginHandler; - /** Field description */ - private Provider securityContextProvicer; - /** Field description */ private Unmarshaller unmarshaller; } diff --git a/scm-webapp/src/main/java/sonia/scm/search/SearchHandler.java b/scm-webapp/src/main/java/sonia/scm/search/SearchHandler.java index 4ecbbf33e0..b06c11b69f 100644 --- a/scm-webapp/src/main/java/sonia/scm/search/SearchHandler.java +++ b/scm-webapp/src/main/java/sonia/scm/search/SearchHandler.java @@ -37,15 +37,16 @@ package sonia.scm.search; import com.google.common.base.Function; import com.google.common.collect.Collections2; -import com.google.inject.Provider; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.cache.Cache; -import sonia.scm.util.SecurityUtil; +import sonia.scm.security.ScmSecurityException; import sonia.scm.util.Util; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -77,11 +78,10 @@ public class SearchHandler * @param cache * @param searchable */ - public SearchHandler(Provider securityContextProvider, - Cache cache, - Searchable searchable) + public SearchHandler(Cache cache, + Searchable searchable) { - this.securityContextProvider = securityContextProvider; + this.cache = cache; this.searchable = searchable; } @@ -107,9 +107,14 @@ public class SearchHandler * @return */ public SearchResults search(String queryString, - Function function) + Function function) { - SecurityUtil.assertIsNotAnonymous(securityContextProvider); + Subject subject = SecurityUtils.getSubject(); + + if (!subject.isAuthenticated()) + { + throw new ScmSecurityException("Authentication is required"); + } if (Util.isEmpty(queryString)) { @@ -202,9 +207,6 @@ public class SearchHandler /** Field description */ protected Searchable searchable; - /** Field description */ - protected Provider securityContextProvider; - /** Field description */ private int maxResults = 5; diff --git a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java index 2b5a89357d..7f78ffca31 100644 --- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java +++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java @@ -39,6 +39,9 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.Subject; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,13 +50,13 @@ import sonia.scm.SCMContextProvider; import sonia.scm.TransformFilter; import sonia.scm.search.SearchRequest; import sonia.scm.search.SearchUtil; +import sonia.scm.security.Role; import sonia.scm.security.ScmSecurityException; import sonia.scm.util.AssertUtil; import sonia.scm.util.CollectionAppender; import sonia.scm.util.IOUtil; import sonia.scm.util.SecurityUtil; import sonia.scm.util.Util; -import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -104,11 +107,9 @@ public class DefaultUserManager extends AbstractUserManager * @param userListenerProvider */ @Inject - public DefaultUserManager( - Provider scurityContextProvider, UserDAO userDAO, - Provider> userListenerProvider) + public DefaultUserManager(UserDAO userDAO, + Provider> userListenerProvider) { - this.scurityContextProvider = scurityContextProvider; this.userDAO = userDAO; this.userListenerProvider = userListenerProvider; } @@ -166,9 +167,16 @@ public class DefaultUserManager extends AbstractUserManager logger.info("create user {} of type {}", user.getName(), user.getType()); } - User currentUser = SecurityUtil.getCurrentUser(scurityContextProvider); + Subject subject = SecurityUtils.getSubject(); - if (!user.equals(currentUser) &&!currentUser.isAdmin()) + if (!subject.isAuthenticated()) + { + throw new ScmSecurityException("user is not authenticated"); + } + + User currentUser = subject.getPrincipals().oneByType(User.class); + + if (!user.equals(currentUser) &&!subject.hasRole(Role.ADMIN)) { throw new ScmSecurityException("admin account is required"); } @@ -202,7 +210,7 @@ public class DefaultUserManager extends AbstractUserManager logger.info("delete user {} of type {}", user.getName(), user.getType()); } - SecurityUtil.assertIsAdmin(scurityContextProvider); + SecurityUtil.assertIsAdmin(); String name = user.getName(); @@ -259,9 +267,17 @@ public class DefaultUserManager extends AbstractUserManager logger.info("modify user {} of type {}", user.getName(), user.getType()); } - User currentUser = SecurityUtil.getCurrentUser(scurityContextProvider); + Subject subject = SecurityUtils.getSubject(); - if (!user.getName().equals(currentUser.getName()) &&!currentUser.isAdmin()) + if (!subject.isAuthenticated()) + { + throw new ScmSecurityException("user is not authenticated"); + } + + User currentUser = subject.getPrincipals().oneByType(User.class); + + if (!user.getName().equals(currentUser.getName()) + &&!subject.hasRole(Role.ADMIN)) { throw new ScmSecurityException("admin account is required"); } @@ -299,7 +315,7 @@ public class DefaultUserManager extends AbstractUserManager logger.info("refresh user {} of type {}", user.getName(), user.getType()); } - SecurityUtil.assertIsAdmin(scurityContextProvider); + SecurityUtil.assertIsAdmin(); User fresh = userDAO.get(user.getName()); @@ -328,7 +344,7 @@ public class DefaultUserManager extends AbstractUserManager } return SearchUtil.search(searchRequest, userDAO.getAll(), - new TransformFilter() + new TransformFilter() { @Override public User accept(User user) @@ -336,7 +352,7 @@ public class DefaultUserManager extends AbstractUserManager User result = null; if (SearchUtil.matchesOne(searchRequest, user.getName(), - user.getDisplayName(), user.getMail())) + user.getDisplayName(), user.getMail())) { result = user.clone(); } @@ -394,7 +410,7 @@ public class DefaultUserManager extends AbstractUserManager @Override public Collection getAll(Comparator comparator) { - SecurityUtil.assertIsAdmin(scurityContextProvider); + SecurityUtil.assertIsAdmin(); List users = new ArrayList(); @@ -424,12 +440,12 @@ public class DefaultUserManager extends AbstractUserManager */ @Override public Collection getAll(Comparator comaparator, int start, - int limit) + int limit) { - SecurityUtil.assertIsAdmin(scurityContextProvider); + SecurityUtil.assertIsAdmin(); return Util.createSubCollection(userDAO.getAll(), comaparator, - new CollectionAppender() + new CollectionAppender() { @Override public void append(Collection collection, User item) @@ -531,9 +547,6 @@ public class DefaultUserManager extends AbstractUserManager //~--- fields --------------------------------------------------------------- - /** Field description */ - private Provider scurityContextProvider; - /** Field description */ private UserDAO userDAO; diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/ApiBasicAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/security/ApiBasicAuthenticationFilter.java index c0e9718ae7..b3386a211f 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/ApiBasicAuthenticationFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/ApiBasicAuthenticationFilter.java @@ -35,8 +35,6 @@ package sonia.scm.web.security; //~--- non-JDK imports -------------------------------------------------------- -import com.google.inject.Inject; -import com.google.inject.Provider; import com.google.inject.Singleton; import sonia.scm.web.filter.BasicAuthenticationFilter; @@ -67,21 +65,6 @@ public class ApiBasicAuthenticationFilter extends BasicAuthenticationFilter /** Field description */ public static final String URI_STATE = "/api/rest/authentication/state"; - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param securityContextProvider - */ - @Inject - public ApiBasicAuthenticationFilter( - Provider securityContextProvider) - { - super(securityContextProvider); - } - //~--- methods -------------------------------------------------------------- /** @@ -97,14 +80,14 @@ public class ApiBasicAuthenticationFilter extends BasicAuthenticationFilter */ @Override protected void doFilter(HttpServletRequest request, - HttpServletResponse response, FilterChain chain) - throws IOException, ServletException + HttpServletResponse response, FilterChain chain) + throws IOException, ServletException { // skip filter on authentication resource if (request.getRequestURI().contains(URI_LOGIN) - || request.getRequestURI().contains(URI_STATE) - || request.getRequestURI().contains(URI_LOGOUT)) + || request.getRequestURI().contains(URI_STATE) + || request.getRequestURI().contains(URI_LOGOUT)) { chain.doFilter(request, response); } @@ -127,9 +110,8 @@ public class ApiBasicAuthenticationFilter extends BasicAuthenticationFilter */ @Override protected void handleUnauthorized(HttpServletRequest request, - HttpServletResponse response, - FilterChain chain) - throws IOException, ServletException + HttpServletResponse response, FilterChain chain) + throws IOException, ServletException { chain.doFilter(request, response); } diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/SecurityUtil.java b/scm-webapp/src/main/java/sonia/scm/web/security/SecurityUtil.java index 84b735cfa4..e5b7f72e7e 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/SecurityUtil.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/SecurityUtil.java @@ -42,7 +42,9 @@ import sonia.scm.SCMContext; /** * * @author Sebastian Sdorra + * @deprecated */ +@Deprecated public class SecurityUtil { diff --git a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java index 840aae469c..d18dac8bb6 100644 --- a/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/user/DefaultUserManagerTest.java @@ -48,6 +48,7 @@ import static org.mockito.Mockito.*; import java.util.HashSet; import java.util.Set; +import org.junit.Before; /** * @@ -55,6 +56,11 @@ import java.util.Set; */ public class DefaultUserManagerTest extends UserManagerTestBase { + + @Before + public void setAdminSubject(){ + setSubject(MockUtil.createAdminSubject()); + } /** * Method description @@ -74,8 +80,7 @@ public class DefaultUserManagerTest extends UserManagerTestBase when(listenerProvider.get()).thenReturn(new HashSet()); XmlUserDAO userDAO = new XmlUserDAO(factory); - - return new DefaultUserManager(MockUtil.getAdminSecurityContextProvider(), - userDAO, listenerProvider); + + return new DefaultUserManager(userDAO, listenerProvider); } } diff --git a/scm-webapp/src/test/java/sonia/scm/web/security/DefaultAuthenticationHandlerTest.java b/scm-webapp/src/test/java/sonia/scm/web/security/DefaultAuthenticationHandlerTest.java index e9a2cc42b9..cdd3c2a116 100644 --- a/scm-webapp/src/test/java/sonia/scm/web/security/DefaultAuthenticationHandlerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/web/security/DefaultAuthenticationHandlerTest.java @@ -44,10 +44,11 @@ import sonia.scm.security.EncryptionHandler; import sonia.scm.security.MessageDigestEncryptionHandler; import sonia.scm.store.JAXBStoreFactory; import sonia.scm.store.StoreFactory; +import sonia.scm.user.DefaultUserManager; import sonia.scm.user.User; import sonia.scm.user.UserListener; import sonia.scm.user.UserTestData; -import sonia.scm.user.DefaultUserManager; +import sonia.scm.user.xml.XmlUserDAO; import sonia.scm.util.MockUtil; import static org.junit.Assert.*; @@ -61,7 +62,6 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import sonia.scm.user.xml.XmlUserDAO; /** * @@ -141,13 +141,16 @@ public class DefaultAuthenticationHandlerTest extends AbstractTestBase when(listenerProvider.get()).thenReturn(new HashSet()); XmlUserDAO userDAO = new XmlUserDAO(storeFactory); - - DefaultUserManager userManager = - new DefaultUserManager(MockUtil.getAdminSecurityContextProvider(), - userDAO, listenerProvider); + + setSubject(MockUtil.createAdminSubject()); + + DefaultUserManager userManager = new DefaultUserManager(userDAO, + listenerProvider); userManager.init(contextProvider); userManager.create(slarti); + clearSubject(); + handler = new DefaultAuthenticationHandler(userManager, enc); handler.init(contextProvider); request = MockUtil.getHttpServletRequest();