From 24ee48356207d04579fa517c09d9a3cd58139723 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 14 Apr 2013 15:13:27 +0200 Subject: [PATCH] start implementation of a new security system to allow global permissions for repositories --- .../java/sonia/scm/repository/Permission.java | 8 +- .../sonia/scm/security/GlobalPermission.java | 207 ++++++++++++++++++ .../sonia/scm/security/PermissionObject.java | 57 +++++ .../scm/security/SecurityConfiguration.java | 80 +++++++ .../SecurityConfigurationChangedEvent.java | 88 ++++++++ .../sonia/scm/security/SecuritySystem.java | 71 ++++++ .../main/java/sonia/scm/ScmServletModule.java | 3 + .../scm/security/DefaultSecuritySystem.java | 132 +++++++++++ .../java/sonia/scm/security/ScmRealm.java | 80 ++++++- .../java/sonia/scm/security/ScmRealmTest.java | 7 + 10 files changed, 725 insertions(+), 8 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/security/GlobalPermission.java create mode 100644 scm-core/src/main/java/sonia/scm/security/PermissionObject.java create mode 100644 scm-core/src/main/java/sonia/scm/security/SecurityConfiguration.java create mode 100644 scm-core/src/main/java/sonia/scm/security/SecurityConfigurationChangedEvent.java create mode 100644 scm-core/src/main/java/sonia/scm/security/SecuritySystem.java create mode 100644 scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java diff --git a/scm-core/src/main/java/sonia/scm/repository/Permission.java b/scm-core/src/main/java/sonia/scm/repository/Permission.java index fe1e442f98..60c6628d61 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Permission.java +++ b/scm-core/src/main/java/sonia/scm/repository/Permission.java @@ -37,6 +37,8 @@ package sonia.scm.repository; import com.google.common.base.Objects; +import sonia.scm.security.PermissionObject; + //~--- JDK imports ------------------------------------------------------------ import java.io.Serializable; @@ -52,7 +54,7 @@ import javax.xml.bind.annotation.XmlRootElement; */ @XmlRootElement(name = "permissions") @XmlAccessorType(XmlAccessType.FIELD) -public class Permission implements Serializable +public class Permission implements PermissionObject, Serializable { /** Field description */ @@ -135,7 +137,7 @@ public class Permission implements Serializable final Permission other = (Permission) obj; return Objects.equal(name, other.name) && Objects.equal(type, other.type) - && Objects.equal(groupPermission, groupPermission); + && Objects.equal(groupPermission, groupPermission); } /** @@ -176,6 +178,7 @@ public class Permission implements Serializable * * @return name of the user or group */ + @Override public String getName() { return name; @@ -198,6 +201,7 @@ public class Permission implements Serializable * * @return true if the permision is a group permission */ + @Override public boolean isGroupPermission() { return groupPermission; diff --git a/scm-core/src/main/java/sonia/scm/security/GlobalPermission.java b/scm-core/src/main/java/sonia/scm/security/GlobalPermission.java new file mode 100644 index 0000000000..252cffacad --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/GlobalPermission.java @@ -0,0 +1,207 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.base.Objects; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.Serializable; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "global-permission") +public final class GlobalPermission implements PermissionObject, Serializable +{ + + /** Field description */ + private static final long serialVersionUID = 4794267414178121515L; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + */ + public GlobalPermission() {} + + /** + * Constructs ... + * + * + * @param id + * @param name + * @param permission + */ + public GlobalPermission(String name, String permission) + { + this(name, false, permission); + } + + /** + * Constructs ... + * + * + * @param id + * @param name + * @param group + * @param permission + */ + public GlobalPermission(String name, boolean groupPermission, String permission) + { + this.name = name; + this.groupPermission = groupPermission; + this.permission = permission; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param obj + * + * @return + */ + @Override + public boolean equals(Object obj) + { + if (obj == null) + { + return false; + } + + if (getClass() != obj.getClass()) + { + return false; + } + + final GlobalPermission other = (GlobalPermission) obj; + + //J- + return Objects.equal(name, other.name) + && Objects.equal(groupPermission, other.groupPermission) + && Objects.equal(permission, other.permission); + //J+ + } + + /** + * Method description + * + * + * @return + */ + @Override + public int hashCode() + { + return Objects.hashCode(name, groupPermission, permission); + } + + /** + * Method description + * + * + * @return + */ + @Override + public String toString() + { + //J- + return Objects.toStringHelper(this) + .add("name", name) + .add("groupPermission", groupPermission) + .add("permisison", permission) + .toString(); + //J+ + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getName() + { + return name; + } + + /** + * Method description + * + * + * @return + */ + public String getPermission() + { + return permission; + } + + /** + * Method description + * + * + * @return + */ + @Override + public boolean isGroupPermission() + { + return groupPermission; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlElement(name = "group") + private boolean groupPermission; + + /** Field description */ + private String name; + + /** Field description */ + private String permission; +} diff --git a/scm-core/src/main/java/sonia/scm/security/PermissionObject.java b/scm-core/src/main/java/sonia/scm/security/PermissionObject.java new file mode 100644 index 0000000000..58b4f065ae --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/PermissionObject.java @@ -0,0 +1,57 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +public interface PermissionObject +{ + + /** + * Method description + * + * + * @return + */ + public String getName(); + + /** + * Method description + * + * + * @return + */ + public boolean isGroupPermission(); +} diff --git a/scm-core/src/main/java/sonia/scm/security/SecurityConfiguration.java b/scm-core/src/main/java/sonia/scm/security/SecurityConfiguration.java new file mode 100644 index 0000000000..aeae5ddbc7 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/SecurityConfiguration.java @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.common.collect.Lists; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.List; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +@XmlRootElement(name = "security") +@XmlAccessorType(XmlAccessType.FIELD) +public class SecurityConfiguration +{ + + /** + * Method description + * + * + * @return + */ + public List getGlobalPermissions() + { + if (globalPermissions == null) + { + globalPermissions = Lists.newArrayList(); + } + + return globalPermissions; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + @XmlElement(name = "permission") + @XmlElementWrapper(name = "global-permissions") + private List globalPermissions; +} diff --git a/scm-core/src/main/java/sonia/scm/security/SecurityConfigurationChangedEvent.java b/scm-core/src/main/java/sonia/scm/security/SecurityConfigurationChangedEvent.java new file mode 100644 index 0000000000..aa541bfaea --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/SecurityConfigurationChangedEvent.java @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +public class SecurityConfigurationChangedEvent +{ + + /** + * Constructs ... + * + * + * @param oldConfiguration + * @param newConfiguration + */ + public SecurityConfigurationChangedEvent( + SecurityConfiguration oldConfiguration, + SecurityConfiguration newConfiguration) + { + this.oldConfiguration = oldConfiguration; + this.newConfiguration = newConfiguration; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public SecurityConfiguration getNewConfiguration() + { + return newConfiguration; + } + + /** + * Method description + * + * + * @return + */ + public SecurityConfiguration getOldConfiguration() + { + return oldConfiguration; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private SecurityConfiguration newConfiguration; + + /** Field description */ + private SecurityConfiguration oldConfiguration; +} diff --git a/scm-core/src/main/java/sonia/scm/security/SecuritySystem.java b/scm-core/src/main/java/sonia/scm/security/SecuritySystem.java new file mode 100644 index 0000000000..cc21dca8ad --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/SecuritySystem.java @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.apache.shiro.subject.PrincipalCollection; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +public interface SecuritySystem +{ + + /** + * Method description + * + * + * @return + */ + public SecurityConfiguration getConfiguration(); + + /** + * Method description + * + * + * @return + */ + public PrincipalCollection getSystemAccount(); + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param configuration + */ + public void setConfiguration(SecurityConfiguration configuration); +} diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 35cb5192e6..dc1255eee2 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -143,6 +143,8 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; import sonia.scm.cache.GuavaCacheManager; +import sonia.scm.security.DefaultSecuritySystem; +import sonia.scm.security.SecuritySystem; /** * @@ -271,6 +273,7 @@ public class ScmServletModule extends ServletModule bind(AuthenticationManager.class, ChainAuthenticatonManager.class); bind(SecurityContext.class).to(BasicSecurityContext.class); bind(WebSecurityContext.class).to(BasicSecurityContext.class); + bind(SecuritySystem.class).to(DefaultSecuritySystem.class); bind(AdministrationContext.class, DefaultAdministrationContext.class); // bind cache diff --git a/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java b/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java new file mode 100644 index 0000000000..36e8be4899 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/security/DefaultSecuritySystem.java @@ -0,0 +1,132 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions in + * binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of SCM-Manager; + * nor the names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; +import com.google.inject.Singleton; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.PrincipalCollection; + +import sonia.scm.event.ScmEventBus; +import sonia.scm.store.Store; +import sonia.scm.store.StoreFactory; + +/** + * + * @author Sebastian Sdorra + * @since 1.31 + */ +@Singleton +public class DefaultSecuritySystem implements SecuritySystem +{ + + /** Field description */ + private static final String NAME = "security"; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param storeFactory + */ + @Inject + public DefaultSecuritySystem(StoreFactory storeFactory) + { + store = storeFactory.getStore(SecurityConfiguration.class, NAME); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public SecurityConfiguration getConfiguration() + { + SecurityConfiguration configuration = store.get(); + + if (configuration == null) + { + configuration = new SecurityConfiguration(); + } + + return configuration; + } + + /** + * Method description + * + * + * @return + */ + @Override + public PrincipalCollection getSystemAccount() + { + throw new UnsupportedOperationException("Not supported yet."); // To change body of generated methods, choose Tools | Templates. + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param newConfiguration + */ + @Override + public void setConfiguration(SecurityConfiguration newConfiguration) + { + SecurityUtils.getSubject().checkRole(Role.ADMIN); + + SecurityConfiguration oldConfiguration = store.get(); + + store.set(newConfiguration); + //J- + ScmEventBus.getInstance().post( + new SecurityConfigurationChangedEvent(oldConfiguration, newConfiguration) + ); + //J+ + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Store store; +} diff --git a/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java b/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java index 8863ffc926..8c2b443b94 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java +++ b/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java @@ -74,6 +74,7 @@ import sonia.scm.repository.PermissionType; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryEvent; +import sonia.scm.repository.RepositoryManager; import sonia.scm.user.User; import sonia.scm.user.UserDAO; import sonia.scm.user.UserEvent; @@ -95,7 +96,6 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import sonia.scm.repository.RepositoryManager; /** * @@ -128,25 +128,28 @@ public class ScmRealm extends AuthorizingRealm * * * @param configuration + * @param securitySystem * @param cacheManager * @param userManager * @param groupManager * @param repositoryDAO * @param userDAO * @param authenticator + * @param manager * @param requestProvider * @param responseProvider */ @Inject - public ScmRealm(ScmConfiguration configuration, CacheManager cacheManager, + public ScmRealm(ScmConfiguration configuration, + SecuritySystem securitySystem, CacheManager cacheManager, UserManager userManager, GroupManager groupManager, RepositoryDAO repositoryDAO, UserDAO userDAO, - AuthenticationManager authenticator, - RepositoryManager manager, + AuthenticationManager authenticator, RepositoryManager manager, Provider requestProvider, Provider responseProvider) { this.configuration = configuration; + this.securitySystem = securitySystem; this.userManager = userManager; this.groupManager = groupManager; this.repositoryDAO = repositoryDAO; @@ -194,6 +197,23 @@ public class ScmRealm extends AuthorizingRealm } } + /** + * Method description + * + * + * @param event + */ + @Subscribe + public void onEvent(SecurityConfigurationChangedEvent event) + { + if (logger.isDebugEnabled()) + { + logger.debug("clear cache, because security configuration has changed"); + } + + cache.clear(); + } + /** * Method description * @@ -474,6 +494,44 @@ public class ScmRealm extends AuthorizingRealm } } + /** + * Method description + * + * + * @param user + * @param groups + * + * @return + */ + private List collectGlobalPermissions(User user, GroupNames groups) + { + if (logger.isTraceEnabled()) + { + logger.trace("collect global permissions for user {}", user.getName()); + } + + List permissions = Lists.newArrayList(); + + List globalPermissions = + securitySystem.getConfiguration().getGlobalPermissions(); + + for (GlobalPermission gp : globalPermissions) + { + if (isUserPermission(user, groups, gp)) + { + if (logger.isTraceEnabled()) + { + logger.trace("add permission {} for user {}", gp.getPermission(), + user.getName()); + } + + permissions.add(gp.getPermission()); + } + } + + return permissions; + } + /** * Method description * @@ -585,7 +643,8 @@ public class ScmRealm extends AuthorizingRealm GroupNames groups) { Set roles = Sets.newHashSet(); - List permissions = null; + List permissions; + List globalPermissions = null; roles.add(Role.USER); @@ -604,12 +663,18 @@ public class ScmRealm extends AuthorizingRealm else { permissions = collectRepositoryPermissions(user, groups); + globalPermissions = collectGlobalPermissions(user, groups); } SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(roles); info.addObjectPermissions(permissions); + if (globalPermissions != null) + { + info.addStringPermissions(globalPermissions); + } + return info; } @@ -734,7 +799,7 @@ public class ScmRealm extends AuthorizingRealm * @return */ private boolean isUserPermission(User user, GroupNames groups, - Permission perm) + PermissionObject perm) { //J- return (perm.isGroupPermission() && groups.contains(perm.getName())) @@ -765,6 +830,9 @@ public class ScmRealm extends AuthorizingRealm /** Field description */ private Provider responseProvider; + /** Field description */ + private SecuritySystem securitySystem; + /** Field description */ private UserDAO userDAO; diff --git a/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java b/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java index aac6c6305a..def745f625 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java @@ -459,9 +459,16 @@ public class ScmRealmTest AuthenticationResult.NOT_FOUND ); + SecuritySystem securitySystem = mock(SecuritySystem.class); + when( + securitySystem.getConfiguration() + ).thenReturn( + new SecurityConfiguration() + ); return new ScmRealm( new ScmConfiguration(), + securitySystem, new MapCacheManager(), userManager, groupManager,