mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-13 08:55:44 +01:00
merge with branch issue-340
This commit is contained in:
@@ -47,7 +47,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.api.rest.UriExtensionsConfig;
|
||||
import sonia.scm.cache.CacheManager;
|
||||
import sonia.scm.cache.EhCacheManager;
|
||||
import sonia.scm.cache.GuavaCacheManager;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.filter.AdminSecurityFilter;
|
||||
@@ -86,13 +86,17 @@ import sonia.scm.resources.ScriptResourceServlet;
|
||||
import sonia.scm.security.CipherHandler;
|
||||
import sonia.scm.security.CipherUtil;
|
||||
import sonia.scm.security.DefaultKeyGenerator;
|
||||
import sonia.scm.security.DefaultSecuritySystem;
|
||||
import sonia.scm.security.EncryptionHandler;
|
||||
import sonia.scm.security.KeyGenerator;
|
||||
import sonia.scm.security.MessageDigestEncryptionHandler;
|
||||
import sonia.scm.security.SecurityContext;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
import sonia.scm.store.BlobStoreFactory;
|
||||
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
||||
import sonia.scm.store.DataStoreFactory;
|
||||
import sonia.scm.store.FileBlobStoreFactory;
|
||||
import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
|
||||
import sonia.scm.store.JAXBDataStoreFactory;
|
||||
import sonia.scm.store.JAXBStoreFactory;
|
||||
import sonia.scm.store.ListenableStoreFactory;
|
||||
@@ -142,7 +146,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import sonia.scm.cache.GuavaCacheManager;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -252,6 +255,8 @@ public class ScmServletModule extends ServletModule
|
||||
// bind core
|
||||
bind(StoreFactory.class, JAXBStoreFactory.class);
|
||||
bind(ListenableStoreFactory.class, JAXBStoreFactory.class);
|
||||
bind(ConfigurationEntryStoreFactory.class,
|
||||
JAXBConfigurationEntryStoreFactory.class);
|
||||
bind(DataStoreFactory.class, JAXBDataStoreFactory.class);
|
||||
bind(BlobStoreFactory.class, FileBlobStoreFactory.class);
|
||||
bind(ScmConfiguration.class).toInstance(config);
|
||||
@@ -271,6 +276,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
|
||||
|
||||
167
scm-webapp/src/main/java/sonia/scm/api/rest/Permission.java
Normal file
167
scm-webapp/src/main/java/sonia/scm/api/rest/Permission.java
Normal file
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* 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.api.rest;
|
||||
|
||||
//~--- 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.XmlRootElement;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@XmlRootElement
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
public class Permission implements Serializable
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final long serialVersionUID = 4320217034601679261L;
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public Permission() {}
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
* @param value
|
||||
*/
|
||||
public Permission(String id, String value)
|
||||
{
|
||||
this.id = id;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param obj
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
final Permission other = (Permission) obj;
|
||||
|
||||
return Objects.equal(id, other.id) && Objects.equal(value, other.value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return Objects.hashCode(id, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
//J-
|
||||
return Objects.toStringHelper(this)
|
||||
.add("id", id)
|
||||
.add("value", value)
|
||||
.toString();
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String id;
|
||||
|
||||
/** Field description */
|
||||
private String value;
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* 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.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import sonia.scm.api.rest.Permission;
|
||||
import sonia.scm.security.AssignedPermission;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
import sonia.scm.security.StoredAssignedPermission;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import javax.ws.rs.core.UriInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
*/
|
||||
public abstract class AbstractPermissionResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param securitySystem
|
||||
* @param name
|
||||
*/
|
||||
protected AbstractPermissionResource(SecuritySystem securitySystem,
|
||||
String name)
|
||||
{
|
||||
this.securitySystem = securitySystem;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract AssignedPermission transformPermission(
|
||||
Permission permission);
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract Predicate<AssignedPermission> getPredicate();
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param uriInfo
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@POST
|
||||
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public Response add(@Context UriInfo uriInfo, Permission permission)
|
||||
{
|
||||
AssignedPermission ap = transformPermission(permission);
|
||||
StoredAssignedPermission sap = securitySystem.addPermission(ap);
|
||||
URI uri = uriInfo.getAbsolutePathBuilder().path(sap.getId()).build();
|
||||
|
||||
return Response.created(uri).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@DELETE
|
||||
@Path("{id}")
|
||||
public Response delete(@PathParam("id") String id)
|
||||
{
|
||||
StoredAssignedPermission sap = getPermission(id);
|
||||
|
||||
securitySystem.deletePermission(sap);
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@PUT
|
||||
@Path("{id}")
|
||||
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public Response update(@PathParam("id") String id, Permission permission)
|
||||
{
|
||||
StoredAssignedPermission sap = getPermission(id);
|
||||
|
||||
securitySystem.modifyPermission(new StoredAssignedPermission(sap.getId(),
|
||||
transformPermission(permission)));
|
||||
|
||||
return Response.noContent().build();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Path("{id}")
|
||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public Permission get(@PathParam("id") String id)
|
||||
{
|
||||
StoredAssignedPermission sap = getPermission(id);
|
||||
|
||||
return new Permission(sap.getId(), sap.getPermission());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GET
|
||||
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
|
||||
public List<Permission> getAll()
|
||||
{
|
||||
return getPermissions(getPredicate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private StoredAssignedPermission getPermission(String id)
|
||||
{
|
||||
StoredAssignedPermission sap = securitySystem.getPermission(id);
|
||||
|
||||
if (sap == null)
|
||||
{
|
||||
throw new WebApplicationException(Status.NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!getPredicate().apply(sap))
|
||||
{
|
||||
throw new WebApplicationException(Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
return sap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param predicate
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<Permission> getPermissions(
|
||||
Predicate<AssignedPermission> predicate)
|
||||
{
|
||||
List<StoredAssignedPermission> permissions =
|
||||
securitySystem.getPermissions(predicate);
|
||||
|
||||
return Lists.transform(permissions,
|
||||
new Function<StoredAssignedPermission, Permission>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public Permission apply(StoredAssignedPermission mgp)
|
||||
{
|
||||
return new Permission(mgp.getId(), mgp.getPermission());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
protected String name;
|
||||
|
||||
/** Field description */
|
||||
private SecuritySystem securitySystem;
|
||||
}
|
||||
@@ -56,6 +56,9 @@ import sonia.scm.ScmState;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.group.GroupNames;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.security.PermissionDescriptor;
|
||||
import sonia.scm.security.Role;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
import sonia.scm.security.Tokens;
|
||||
import sonia.scm.user.User;
|
||||
import sonia.scm.user.UserManager;
|
||||
@@ -64,6 +67,7 @@ import sonia.scm.user.UserManager;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
@@ -105,16 +109,18 @@ public class AuthenticationResource
|
||||
* @param repositoryManger
|
||||
* @param userManager
|
||||
* @param securityContextProvider
|
||||
* @param securitySystem
|
||||
*/
|
||||
@Inject
|
||||
public AuthenticationResource(SCMContextProvider contextProvider,
|
||||
ScmConfiguration configuration, RepositoryManager repositoryManger,
|
||||
UserManager userManager)
|
||||
UserManager userManager, SecuritySystem securitySystem)
|
||||
{
|
||||
this.contextProvider = contextProvider;
|
||||
this.configuration = configuration;
|
||||
this.repositoryManger = repositoryManger;
|
||||
this.userManager = userManager;
|
||||
this.securitySystem = securitySystem;
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
@@ -295,7 +301,8 @@ public class AuthenticationResource
|
||||
*/
|
||||
private ScmState createAnonymousState()
|
||||
{
|
||||
return createState(SCMContext.ANONYMOUS, Collections.EMPTY_LIST);
|
||||
return createState(SCMContext.ANONYMOUS, Collections.EMPTY_LIST,
|
||||
Collections.EMPTY_LIST);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,7 +321,14 @@ public class AuthenticationResource
|
||||
User user = collection.oneByType(User.class);
|
||||
GroupNames groups = collection.oneByType(GroupNames.class);
|
||||
|
||||
return createState(user, groups.getCollection());
|
||||
List<PermissionDescriptor> ap = Collections.EMPTY_LIST;
|
||||
|
||||
if (subject.hasRole(Role.ADMIN))
|
||||
{
|
||||
ap = securitySystem.getAvailablePermissions();
|
||||
}
|
||||
|
||||
return createState(user, groups.getCollection(), ap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,14 +337,16 @@ public class AuthenticationResource
|
||||
*
|
||||
* @param user
|
||||
* @param groups
|
||||
* @param availablePermissions
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private ScmState createState(User user, Collection<String> groups)
|
||||
private ScmState createState(User user, Collection<String> groups,
|
||||
List<PermissionDescriptor> availablePermissions)
|
||||
{
|
||||
return new ScmState(contextProvider, user, groups,
|
||||
repositoryManger.getConfiguredTypes(), userManager.getDefaultType(),
|
||||
new ScmClientConfig(configuration));
|
||||
new ScmClientConfig(configuration), availablePermissions);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
@@ -344,6 +360,9 @@ public class AuthenticationResource
|
||||
/** Field description */
|
||||
private RepositoryManager repositoryManger;
|
||||
|
||||
/** Field description */
|
||||
private SecuritySystem securitySystem;
|
||||
|
||||
/** Field description */
|
||||
private UserManager userManager;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* 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.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import sonia.scm.api.rest.Permission;
|
||||
import sonia.scm.security.AssignedPermission;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class GroupPermissionResource extends AbstractPermissionResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param securitySystem
|
||||
* @param name
|
||||
*/
|
||||
public GroupPermissionResource(SecuritySystem securitySystem, String name)
|
||||
{
|
||||
super(securitySystem, name);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected AssignedPermission transformPermission(Permission permission)
|
||||
{
|
||||
return new AssignedPermission(name, true, permission.getValue());
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Predicate<AssignedPermission> getPredicate()
|
||||
{
|
||||
return new GroupPredicate(name);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/05/01
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class GroupPredicate implements Predicate<AssignedPermission>
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public GroupPredicate(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param input
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean apply(AssignedPermission input)
|
||||
{
|
||||
return input.isGroupPermission() && input.getName().equals(name);
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
|
||||
import sonia.scm.security.Role;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
@Path("security/permission")
|
||||
public class SecuritySystemResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param system
|
||||
*/
|
||||
@Inject
|
||||
public SecuritySystemResource(SecuritySystem system)
|
||||
{
|
||||
this.system = system;
|
||||
|
||||
// only administrators can use this resource
|
||||
SecurityUtils.getSubject().checkRole(Role.ADMIN);
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param group
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Path("group/{group}")
|
||||
public GroupPermissionResource getGroupSubResource(
|
||||
@PathParam("group") String group)
|
||||
{
|
||||
return new GroupPermissionResource(system, group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param user
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Path("user/{user}")
|
||||
public UserPermissionResource getUserSubResource(
|
||||
@PathParam("user") String user)
|
||||
{
|
||||
return new UserPermissionResource(system, user);
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private SecuritySystem system;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* 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.api.rest.resources;
|
||||
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import sonia.scm.api.rest.Permission;
|
||||
import sonia.scm.security.AssignedPermission;
|
||||
import sonia.scm.security.SecuritySystem;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
*/
|
||||
public class UserPermissionResource extends AbstractPermissionResource
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param securitySystem
|
||||
* @param name
|
||||
*/
|
||||
public UserPermissionResource(SecuritySystem securitySystem, String name)
|
||||
{
|
||||
super(securitySystem, name);
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected AssignedPermission transformPermission(Permission permission)
|
||||
{
|
||||
return new AssignedPermission(name, permission.getValue());
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
protected Predicate<AssignedPermission> getPredicate()
|
||||
{
|
||||
return new UserPredicate(name);
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/05/01
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
private static class UserPredicate implements Predicate<AssignedPermission>
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public UserPredicate(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
//~--- methods ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param input
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean apply(AssignedPermission input)
|
||||
{
|
||||
return !input.isGroupPermission() && input.getName().equals(name);
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private String name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,501 @@
|
||||
/**
|
||||
* 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.Predicate;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableList.Builder;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import sonia.scm.HandlerEvent;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.event.Subscriber;
|
||||
import sonia.scm.group.GroupEvent;
|
||||
import sonia.scm.store.ConfigurationEntryStore;
|
||||
import sonia.scm.store.ConfigurationEntryStoreFactory;
|
||||
import sonia.scm.user.UserEvent;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
/**
|
||||
* TODO add events
|
||||
*
|
||||
* @author Sebastian Sdorra
|
||||
* @since 1.31
|
||||
*/
|
||||
@Singleton
|
||||
@Subscriber(async = true)
|
||||
public class DefaultSecuritySystem implements SecuritySystem
|
||||
{
|
||||
|
||||
/** Field description */
|
||||
private static final String NAME = "security";
|
||||
|
||||
/** Field description */
|
||||
private static final String PERMISSION_DESCRIPTOR =
|
||||
"META-INF/scm/permissions.xml";
|
||||
|
||||
/**
|
||||
* the logger for DefaultSecuritySystem
|
||||
*/
|
||||
private static final Logger logger =
|
||||
LoggerFactory.getLogger(DefaultSecuritySystem.class);
|
||||
|
||||
//~--- constructors ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*
|
||||
* @param storeFactory
|
||||
*/
|
||||
@Inject
|
||||
public DefaultSecuritySystem(ConfigurationEntryStoreFactory storeFactory)
|
||||
{
|
||||
store = storeFactory.getStore(AssignedPermission.class, NAME);
|
||||
readAvailablePermissions();
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public StoredAssignedPermission addPermission(AssignedPermission permission)
|
||||
{
|
||||
assertIsAdmin();
|
||||
|
||||
String id = store.put(permission);
|
||||
|
||||
StoredAssignedPermission sap = new StoredAssignedPermission(id, permission);
|
||||
|
||||
//J-
|
||||
ScmEventBus.getInstance().post(
|
||||
new StoredAssignedPermissionEvent(HandlerEvent.CREATE, sap)
|
||||
);
|
||||
//J+
|
||||
|
||||
return sap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*/
|
||||
@Override
|
||||
public void deletePermission(StoredAssignedPermission permission)
|
||||
{
|
||||
assertIsAdmin();
|
||||
store.remove(permission.getId());
|
||||
//J-
|
||||
ScmEventBus.getInstance().post(
|
||||
new StoredAssignedPermissionEvent(HandlerEvent.CREATE, permission)
|
||||
);
|
||||
//J+
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
@Override
|
||||
public void deletePermission(String id)
|
||||
{
|
||||
assertIsAdmin();
|
||||
|
||||
AssignedPermission ap = store.get(id);
|
||||
|
||||
if (ap != null)
|
||||
{
|
||||
deletePermission(new StoredAssignedPermission(id, ap));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@Subscribe
|
||||
public void handleEvent(final UserEvent event)
|
||||
{
|
||||
if (event.getEventType() == HandlerEvent.DELETE)
|
||||
{
|
||||
deletePermissions(new Predicate<AssignedPermission>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean apply(AssignedPermission p)
|
||||
{
|
||||
return !p.isGroupPermission()
|
||||
&& event.getItem().getName().equals(p.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@Subscribe
|
||||
public void handleEvent(final GroupEvent event)
|
||||
{
|
||||
if (event.getEventType() == HandlerEvent.DELETE)
|
||||
{
|
||||
deletePermissions(new Predicate<AssignedPermission>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean apply(AssignedPermission p)
|
||||
{
|
||||
return p.isGroupPermission()
|
||||
&& event.getItem().getName().equals(p.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param permission
|
||||
*/
|
||||
@Override
|
||||
public void modifyPermission(StoredAssignedPermission permission)
|
||||
{
|
||||
assertIsAdmin();
|
||||
|
||||
synchronized (store)
|
||||
{
|
||||
store.remove(permission.getId());
|
||||
store.put(permission.getId(), new AssignedPermission(permission));
|
||||
}
|
||||
|
||||
//J-
|
||||
ScmEventBus.getInstance().post(
|
||||
new StoredAssignedPermissionEvent(HandlerEvent.CREATE, permission)
|
||||
);
|
||||
//J+
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<StoredAssignedPermission> getAllPermissions()
|
||||
{
|
||||
return getPermissions(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<PermissionDescriptor> getAvailablePermissions()
|
||||
{
|
||||
assertIsAdmin();
|
||||
|
||||
return availablePermissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param id
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public StoredAssignedPermission getPermission(String id)
|
||||
{
|
||||
assertIsAdmin();
|
||||
|
||||
StoredAssignedPermission sap = null;
|
||||
AssignedPermission ap = store.get(id);
|
||||
|
||||
if (ap != null)
|
||||
{
|
||||
sap = new StoredAssignedPermission(id, ap);
|
||||
}
|
||||
|
||||
return sap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param predicate
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<StoredAssignedPermission> getPermissions(
|
||||
Predicate<AssignedPermission> predicate)
|
||||
{
|
||||
Builder<StoredAssignedPermission> permissions = ImmutableList.builder();
|
||||
|
||||
for (Entry<String, AssignedPermission> e : store.getAll().entrySet())
|
||||
{
|
||||
if ((predicate == null) || predicate.apply(e.getValue()))
|
||||
{
|
||||
permissions.add(new StoredAssignedPermission(e.getKey(), e.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return permissions.build();
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
private void assertIsAdmin()
|
||||
{
|
||||
SecurityUtils.getSubject().checkRole(Role.ADMIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param predicate
|
||||
*/
|
||||
private void deletePermissions(Predicate<AssignedPermission> predicate)
|
||||
{
|
||||
List<StoredAssignedPermission> permissions = getPermissions(predicate);
|
||||
|
||||
for (StoredAssignedPermission permission : permissions)
|
||||
{
|
||||
deletePermission(permission);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param context
|
||||
* @param descriptorUrl
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<PermissionDescriptor> parsePermissionDescriptor(
|
||||
JAXBContext context, URL descriptorUrl)
|
||||
{
|
||||
List<PermissionDescriptor> descriptors = Collections.EMPTY_LIST;
|
||||
|
||||
try
|
||||
{
|
||||
PermissionDescriptors descriptorWrapper =
|
||||
(PermissionDescriptors) context.createUnmarshaller().unmarshal(
|
||||
descriptorUrl);
|
||||
|
||||
descriptors = descriptorWrapper.getPermissions();
|
||||
|
||||
logger.debug("found {} permissions at {}", descriptors.size(),
|
||||
descriptorUrl);
|
||||
logger.trace("permissions from {}: {}", descriptorUrl, descriptors);
|
||||
}
|
||||
catch (JAXBException ex)
|
||||
{
|
||||
logger.error("could not parse permission descriptor", ex);
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*/
|
||||
private void readAvailablePermissions()
|
||||
{
|
||||
Builder<PermissionDescriptor> builder = ImmutableList.builder();
|
||||
|
||||
try
|
||||
{
|
||||
JAXBContext context =
|
||||
JAXBContext.newInstance(PermissionDescriptors.class);
|
||||
|
||||
Enumeration<URL> descirptorEnum =
|
||||
getClassLoader().getResources(PERMISSION_DESCRIPTOR);
|
||||
|
||||
while (descirptorEnum.hasMoreElements())
|
||||
{
|
||||
URL descriptorUrl = descirptorEnum.nextElement();
|
||||
|
||||
logger.debug("read permission descriptor from {}", descriptorUrl);
|
||||
|
||||
builder.addAll(parsePermissionDescriptor(context, descriptorUrl));
|
||||
}
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.error("could not read permission descriptors", ex);
|
||||
}
|
||||
catch (JAXBException ex)
|
||||
{
|
||||
logger.error(
|
||||
"could not create jaxb context to read permission descriptors", ex);
|
||||
}
|
||||
|
||||
availablePermissions = builder.build();
|
||||
}
|
||||
|
||||
//~--- get methods ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private ClassLoader getClassLoader()
|
||||
{
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
if (classLoader == null)
|
||||
{
|
||||
logger.warn("could not find context classloader, use default");
|
||||
|
||||
classLoader = DefaultSecuritySystem.class.getClassLoader();
|
||||
}
|
||||
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
//~--- inner classes --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Class description
|
||||
*
|
||||
*
|
||||
* @version Enter version here..., 13/04/30
|
||||
* @author Enter your name here...
|
||||
*/
|
||||
@XmlRootElement(name = "permissions")
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
private static class PermissionDescriptors
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructs ...
|
||||
*
|
||||
*/
|
||||
public PermissionDescriptors() {}
|
||||
|
||||
//~--- get methods --------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public List<PermissionDescriptor> getPermissions()
|
||||
{
|
||||
if (permissions == null)
|
||||
{
|
||||
permissions = Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
//~--- fields -------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
@XmlElement(name = "permission")
|
||||
private List<PermissionDescriptor> permissions;
|
||||
}
|
||||
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
/** Field description */
|
||||
private final ConfigurationEntryStore<AssignedPermission> store;
|
||||
|
||||
/** Field description */
|
||||
private List<PermissionDescriptor> availablePermissions;
|
||||
}
|
||||
@@ -36,6 +36,7 @@ package sonia.scm.security;
|
||||
//~--- non-JDK imports --------------------------------------------------------
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
@@ -128,6 +129,7 @@ public class ScmRealm extends AuthorizingRealm
|
||||
*
|
||||
*
|
||||
* @param configuration
|
||||
* @param securitySystem
|
||||
* @param cacheManager
|
||||
* @param userManager
|
||||
* @param groupManager
|
||||
@@ -139,7 +141,8 @@ public class ScmRealm extends AuthorizingRealm
|
||||
* @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,
|
||||
@@ -147,6 +150,7 @@ public class ScmRealm extends AuthorizingRealm
|
||||
Provider<HttpServletResponse> responseProvider)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.securitySystem = securitySystem;
|
||||
this.userManager = userManager;
|
||||
this.groupManager = groupManager;
|
||||
this.repositoryDAO = repositoryDAO;
|
||||
@@ -194,6 +198,27 @@ public class ScmRealm extends AuthorizingRealm
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param event
|
||||
*/
|
||||
@Subscribe
|
||||
public void onEvent(StoredAssignedPermissionEvent event)
|
||||
{
|
||||
if (event.getEventType().isPost())
|
||||
{
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
logger.debug("clear cache, because permission {} has changed",
|
||||
event.getPermission().getId());
|
||||
}
|
||||
|
||||
cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -474,6 +499,51 @@ public class ScmRealm extends AuthorizingRealm
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
*
|
||||
* @param user
|
||||
* @param groups
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<String> collectGlobalPermissions(final User user,
|
||||
final GroupNames groups)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("collect global permissions for user {}", user.getName());
|
||||
}
|
||||
|
||||
List<String> permissions = Lists.newArrayList();
|
||||
|
||||
List<StoredAssignedPermission> globalPermissions =
|
||||
securitySystem.getPermissions(new Predicate<AssignedPermission>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public boolean apply(AssignedPermission input)
|
||||
{
|
||||
return isUserPermission(user, groups, input);
|
||||
}
|
||||
});
|
||||
|
||||
for (StoredAssignedPermission gp : globalPermissions)
|
||||
{
|
||||
if (logger.isTraceEnabled())
|
||||
{
|
||||
logger.trace("add permission {} for user {}", gp.getPermission(),
|
||||
user.getName());
|
||||
}
|
||||
|
||||
permissions.add(gp.getPermission());
|
||||
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method description
|
||||
*
|
||||
@@ -585,7 +655,8 @@ public class ScmRealm extends AuthorizingRealm
|
||||
GroupNames groups)
|
||||
{
|
||||
Set<String> roles = Sets.newHashSet();
|
||||
List<org.apache.shiro.authz.Permission> permissions = null;
|
||||
List<org.apache.shiro.authz.Permission> permissions;
|
||||
List<String> globalPermissions = null;
|
||||
|
||||
roles.add(Role.USER);
|
||||
|
||||
@@ -604,12 +675,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;
|
||||
}
|
||||
|
||||
@@ -737,7 +814,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()))
|
||||
@@ -768,6 +845,9 @@ public class ScmRealm extends AuthorizingRealm
|
||||
/** Field description */
|
||||
private Provider<HttpServletResponse> responseProvider;
|
||||
|
||||
/** Field description */
|
||||
private SecuritySystem securitySystem;
|
||||
|
||||
/** Field description */
|
||||
private UserDAO userDAO;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user