From ea39ecb365e580b05092051e895f8e4f9eef5684 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 26 May 2013 13:14:59 +0200 Subject: [PATCH] added assigned permissions to ScmState --- .../src/main/java/sonia/scm/ScmState.java | 32 ++++++++++- .../scm/security/RepositoryPermission.java | 26 ++++++++- .../scm/security/StringablePermission.java | 55 +++++++++++++++++++ .../resources/AuthenticationResource.java | 33 +++++++++-- .../scm/security/PermissionCollector.java | 3 +- .../RepositoryPermissionResolver.java | 6 +- 6 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/security/StringablePermission.java diff --git a/scm-core/src/main/java/sonia/scm/ScmState.java b/scm-core/src/main/java/sonia/scm/ScmState.java index a04413f199..9e5baccf95 100644 --- a/scm-core/src/main/java/sonia/scm/ScmState.java +++ b/scm-core/src/main/java/sonia/scm/ScmState.java @@ -126,7 +126,7 @@ public class ScmState String defaultUserType, ScmClientConfig clientConfig) { this(provider, user, groups, repositoryTypes, defaultUserType, - clientConfig, null); + clientConfig, null, null); } /** @@ -139,6 +139,7 @@ public class ScmState * @param repositoryTypes available repository types * @param defaultUserType default user type * @param clientConfig client configuration + * @param assignedPermission * @param availablePermissions list of available permissions * * @since 1.31 @@ -146,6 +147,7 @@ public class ScmState public ScmState(SCMContextProvider provider, User user, Collection groups, Collection repositoryTypes, String defaultUserType, ScmClientConfig clientConfig, + List assignedPermission, List availablePermissions) { this.version = provider.getVersion(); @@ -154,11 +156,24 @@ public class ScmState this.repositoryTypes = repositoryTypes; this.clientConfig = clientConfig; this.defaultUserType = defaultUserType; + this.assignedPermissions = assignedPermission; this.availablePermissions = availablePermissions; } //~--- get methods ---------------------------------------------------------- + /** + * Return a list of assigned permissions. + * + * + * @return list of assigned permissions + * @since 1.31 + */ + public List getAssignedPermissions() + { + return assignedPermissions; + } + /** * Returns a list of available global permissions. * @@ -253,6 +268,18 @@ public class ScmState //~--- set methods ---------------------------------------------------------- + /** + * Sets a list of assigned permissions. + * + * + * @param assignedPermissions list of assigned permissions + * @since 1.31 + */ + public void setAssignedPermissions(List assignedPermissions) + { + this.assignedPermissions = assignedPermissions; + } + /** * Sets a list of available global permissions. * @@ -349,6 +376,9 @@ public class ScmState //~--- fields --------------------------------------------------------------- + /** Field description */ + private List assignedPermissions; + /** * Avaliable global permission * @since 1.31 diff --git a/scm-core/src/main/java/sonia/scm/security/RepositoryPermission.java b/scm-core/src/main/java/sonia/scm/security/RepositoryPermission.java index b1ffcde938..f697e82dfd 100644 --- a/scm-core/src/main/java/sonia/scm/security/RepositoryPermission.java +++ b/scm-core/src/main/java/sonia/scm/security/RepositoryPermission.java @@ -30,6 +30,7 @@ */ + package sonia.scm.security; //~--- non-JDK imports -------------------------------------------------------- @@ -51,9 +52,16 @@ import java.io.Serializable; * @author Sebastian Sdorra * @since 1.21 */ -public final class RepositoryPermission implements Permission, Serializable +public final class RepositoryPermission + implements StringablePermission, Serializable { + /** + * Type string of the permission + * @since 1.31 + */ + public static final String TYPE = "repository"; + /** Field description */ public static final String WILDCARD = "*"; @@ -175,6 +183,22 @@ public final class RepositoryPermission implements Permission, Serializable //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @return + */ + @Override + public String getAsString() + { + StringBuilder buffer = new StringBuilder(TYPE); + + buffer.append(":").append(repositoryId).append(":").append(permissionType); + + return buffer.toString(); + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/security/StringablePermission.java b/scm-core/src/main/java/sonia/scm/security/StringablePermission.java new file mode 100644 index 0000000000..f867f31340 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/StringablePermission.java @@ -0,0 +1,55 @@ +/** + * 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.authz.Permission; + +/** + * Permission that can be represented by a string. {@link StringablePermission} + * are the only permissions which are pushed to the ui. + * + * @author Sebastian Sdorra + * @since 1.31 + */ +public interface StringablePermission extends Permission +{ + + /** + * Return string representation of the permission. + * + * + * @return string representation of the permission + */ + public String getAsString(); +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java index 346c07445e..d5f93fadb5 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java @@ -35,11 +35,14 @@ package sonia.scm.api.rest.resources; //~--- non-JDK imports -------------------------------------------------------- +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableList.Builder; import com.google.inject.Inject; import com.google.inject.Singleton; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authz.Permission; import org.apache.shiro.subject.PrincipalCollection; import org.apache.shiro.subject.Subject; @@ -56,9 +59,11 @@ import sonia.scm.ScmState; import sonia.scm.config.ScmConfiguration; import sonia.scm.group.GroupNames; import sonia.scm.repository.RepositoryManager; +import sonia.scm.security.PermissionCollector; import sonia.scm.security.PermissionDescriptor; import sonia.scm.security.Role; import sonia.scm.security.SecuritySystem; +import sonia.scm.security.StringablePermission; import sonia.scm.security.Tokens; import sonia.scm.user.User; import sonia.scm.user.UserManager; @@ -110,17 +115,20 @@ public class AuthenticationResource * @param userManager * @param securityContextProvider * @param securitySystem + * @param collector */ @Inject public AuthenticationResource(SCMContextProvider contextProvider, ScmConfiguration configuration, RepositoryManager repositoryManger, - UserManager userManager, SecuritySystem securitySystem) + UserManager userManager, SecuritySystem securitySystem, + PermissionCollector collector) { this.contextProvider = contextProvider; this.configuration = configuration; this.repositoryManger = repositoryManger; this.userManager = userManager; this.securitySystem = securitySystem; + this.permissionCollector = collector; } //~--- methods -------------------------------------------------------------- @@ -302,7 +310,7 @@ public class AuthenticationResource private ScmState createAnonymousState() { return createState(SCMContext.ANONYMOUS, Collections.EMPTY_LIST, - Collections.EMPTY_LIST); + Collections.EMPTY_LIST, Collections.EMPTY_LIST); } /** @@ -328,7 +336,18 @@ public class AuthenticationResource ap = securitySystem.getAvailablePermissions(); } - return createState(user, groups.getCollection(), ap); + Builder builder = ImmutableList.builder(); + + for (Permission p : permissionCollector.collect(user, groups)) + { + if (p instanceof StringablePermission) + { + builder.add(((StringablePermission) p).getAsString()); + } + + } + + return createState(user, groups.getCollection(), builder.build(), ap); } /** @@ -337,16 +356,19 @@ public class AuthenticationResource * * @param user * @param groups + * @param assignedPermissions * @param availablePermissions * * @return */ private ScmState createState(User user, Collection groups, + List assignedPermissions, List availablePermissions) { return new ScmState(contextProvider, user, groups, repositoryManger.getConfiguredTypes(), userManager.getDefaultType(), - new ScmClientConfig(configuration), availablePermissions); + new ScmClientConfig(configuration), assignedPermissions, + availablePermissions); } //~--- fields --------------------------------------------------------------- @@ -357,6 +379,9 @@ public class AuthenticationResource /** Field description */ private SCMContextProvider contextProvider; + /** Field description */ + private PermissionCollector permissionCollector; + /** Field description */ private RepositoryManager repositoryManger; diff --git a/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java b/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java index 3ce66ca926..dad5d91910 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java @@ -34,6 +34,7 @@ package sonia.scm.security; //~--- non-JDK imports -------------------------------------------------------- import com.google.common.base.Predicate; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; import com.google.inject.Inject; import com.google.inject.Singleton; @@ -100,7 +101,7 @@ public class PermissionCollector */ public List collect(User user, GroupNames groups) { - Builder builder = new Builder(); + Builder builder = ImmutableList.builder(); collectRepositoryPermissions(builder, user, groups); collectGlobalPermissions(builder, user, groups); diff --git a/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionResolver.java b/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionResolver.java index 4d4417aaa1..4ef83c1640 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionResolver.java +++ b/scm-webapp/src/main/java/sonia/scm/security/RepositoryPermissionResolver.java @@ -30,6 +30,7 @@ */ + package sonia.scm.security; //~--- non-JDK imports -------------------------------------------------------- @@ -55,9 +56,6 @@ import java.util.Locale; public class RepositoryPermissionResolver implements PermissionResolver { - /** Field description */ - private static final String TYPE_REPOSITORY = "repository"; - /** * the logger for RepositoryPermissionResolver */ @@ -86,7 +84,7 @@ public class RepositoryPermissionResolver implements PermissionResolver { String type = permissionIt.next(); - if (type.equals(TYPE_REPOSITORY)) + if (type.equals(RepositoryPermission.TYPE)) { permission = createRepositoryPermission(permissionIt); }