diff --git a/pom.xml b/pom.xml
index 652e4ef2c0..e0a388a48b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,15 @@
scm-manager release repository
http://maven.scm-manager.org/nexus/content/groups/public
+
+
+ ossrh
+ https://oss.sonatype.org/content/repositories/snapshots
+
+ true
+ daily
+
+
@@ -493,6 +502,7 @@
9.2.10.v20150310
+ 1.0.0-SNAPSHOT
1.2.3
diff --git a/scm-core/pom.xml b/scm-core/pom.xml
index 2bbb656ea0..7045c52051 100644
--- a/scm-core/pom.xml
+++ b/scm-core/pom.xml
@@ -114,6 +114,19 @@
provided
+
+ com.github.sdorra
+ ssp-lib
+ ${ssp.version}
+
+
+
+ com.github.sdorra
+ ssp-processor
+ ${ssp.version}
+ true
+
+
diff --git a/scm-core/src/main/java/sonia/scm/group/Group.java b/scm-core/src/main/java/sonia/scm/group/Group.java
index f25f0c0124..8bffc22260 100644
--- a/scm-core/src/main/java/sonia/scm/group/Group.java
+++ b/scm-core/src/main/java/sonia/scm/group/Group.java
@@ -35,6 +35,8 @@ package sonia.scm.group;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionObject;
+import com.github.sdorra.ssp.StaticPermissions;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
@@ -60,10 +62,11 @@ import javax.xml.bind.annotation.XmlRootElement;
*
* @author Sebastian Sdorra
*/
+@StaticPermissions("group")
@XmlRootElement(name = "groups")
@XmlAccessorType(XmlAccessType.FIELD)
public class Group extends BasicPropertiesAware
- implements ModelObject, Iterable
+ implements ModelObject, Iterable, PermissionObject
{
/** Field description */
diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java
index fb4dde3256..b0a976db55 100644
--- a/scm-core/src/main/java/sonia/scm/repository/Repository.java
+++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java
@@ -35,6 +35,8 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionObject;
+import com.github.sdorra.ssp.StaticPermissions;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;
@@ -61,9 +63,13 @@ import javax.xml.bind.annotation.XmlRootElement;
*
* @author Sebastian Sdorra
*/
+@StaticPermissions(
+ value = "repository",
+ permissions = {"read", "write", "modify", "delete", "healthCheck"}
+)
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "repositories")
-public class Repository extends BasicPropertiesAware implements ModelObject
+public class Repository extends BasicPropertiesAware implements ModelObject, PermissionObject
{
/** Field description */
diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryPermissions.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryPermissions.java
deleted file mode 100644
index a0cf08cdc1..0000000000
--- a/scm-core/src/main/java/sonia/scm/repository/RepositoryPermissions.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- * Copyright (c) 2014, 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.repository;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import sonia.scm.security.PermissionActionCheck;
-import sonia.scm.security.PermissionCheck;
-
-/**
- * Permission checks for repository related permissions.
- *
- * @author Sebastian Sdorra
- * @since 2.0.0
- */
-public final class RepositoryPermissions
-{
-
- /** create permission */
- public static final String ACTION_CREATE = "create";
-
- /** delete permission */
- public static final String ACTION_DELETE = "delete";
-
- /** modify permission */
- public static final String ACTION_MODIFY = "modify";
-
- /** health check permission implies modify permission */
- public static final String ACTION_HC = "hc,".concat(ACTION_MODIFY);
-
- /** read permission */
- public static final String ACTION_READ = "read";
-
- /** write permission */
- public static final String ACTION_WRITE = "write";
-
- /** permission separator */
- public static final String SEPARATOR = ":";
-
- /** permission action separator */
- public static final String SEPERATOR_ACTION = ",";
-
- /** permission main type */
- public static final String TYPE = "repository";
-
- //~--- constructors ---------------------------------------------------------
-
- private RepositoryPermissions() {}
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Returns permission check for create action.
- *
- * @return permission check for create action
- */
- public static PermissionCheck create()
- {
- return check(ACTION_CREATE);
- }
-
- /**
- * Returns permission check for delete action.
- *
- * @param r repository for permission check
- *
- * @return permission check for delete action
- */
- public static PermissionCheck delete(Repository r)
- {
- return delete(r.getId());
- }
-
- /**
- * Returns permission check for delete action.
- *
- * @param id id of repository for permission check
- *
- * @return permission check for delete action
- */
- public static PermissionCheck delete(String id)
- {
- return check(ACTION_DELETE.concat(SEPARATOR).concat(id));
- }
-
- /**
- * Returns permission action check for delete action.
- *
- * @return permission action check for delete action
- */
- public static PermissionActionCheck delete()
- {
- return actionCheck(ACTION_DELETE);
- }
-
- /**
- * Returns permission check for health check action.
- *
- * @param id id of repository for permission check
- *
- * @return permission check for health check action
- */
- public static PermissionCheck healthCheck(String id)
- {
- return check(ACTION_HC.concat(SEPARATOR).concat(id));
- }
-
- /**
- * Returns permission action check for health check action.
- *
- * @return permission action check for health check action.
- */
- public static PermissionActionCheck healthCheck()
- {
- return new PermissionActionCheck<>(
- TYPE.concat(SEPARATOR).concat(ACTION_HC));
- }
-
- /**
- * Returns permission check for health check action.
- *
- * @param r repository for permission check
- *
- * @return permission check for health check action
- */
- public static PermissionCheck healthCheck(Repository r)
- {
- return healthCheck(r.getId());
- }
-
- /**
- * Returns permission action check for modify action.
- *
- * @param r repository for permission check
- *
- * @return permission action check for modify action
- */
- public static PermissionCheck modify(Repository r)
- {
- return modify(r.getId());
- }
-
- /**
- * Returns permission action check for modify action.
- *
- *
- * @param id id of repository for permission check
- *
- * @return permission action check for modify action
- */
- public static PermissionCheck modify(String id)
- {
- return check(ACTION_MODIFY.concat(SEPARATOR).concat(id));
- }
-
- /**
- * Returns permission action check for modify action.
- *
- * @return permission action check for modify action
- */
- public static PermissionActionCheck modify()
- {
- return actionCheck(ACTION_MODIFY);
- }
-
- /**
- * Returns permission check for read action.
- *
- * @param id id of repository for permission check
- *
- * @return permission check for read action
- */
- public static PermissionCheck read(String id)
- {
- return check(ACTION_READ.concat(SEPARATOR).concat(id));
- }
-
- /**
- * Returns permission check for read action.
- *
- * @param r repository for permission check
- *
- * @return permission check for read action
- */
- public static PermissionCheck read(Repository r)
- {
- return read(r.getId());
- }
-
- /**
- * Returns permission action check for read action.
- *
- * @return permission action check for read action
- */
- public static PermissionActionCheck read()
- {
- return actionCheck(ACTION_READ);
- }
-
- /**
- * Returns permission check for write action.
- *
- * @param id id of repository for permission check
- *
- * @return permission check for write action
- */
- public static PermissionCheck write(String id)
- {
- return check(ACTION_WRITE.concat(SEPARATOR).concat(id));
- }
-
- /**
- * Returns permission check for write action.
- *
- * @param r repository for permission check
- *
- * @return permission check for write action
- */
- public static PermissionCheck write(Repository r)
- {
- return write(r.getId());
- }
-
- /**
- * Return permission action check for write action.
- *
- * @return permission action check for write action
- */
- public static PermissionActionCheck write()
- {
- return actionCheck(ACTION_WRITE);
- }
-
- private static PermissionActionCheck actionCheck(String action)
- {
- return new PermissionActionCheck<>(TYPE.concat(SEPARATOR).concat(action));
- }
-
- private static PermissionCheck check(String permission)
- {
- return new PermissionCheck(TYPE.concat(SEPARATOR).concat(permission));
- }
-}
diff --git a/scm-core/src/main/java/sonia/scm/security/PermissionActionCheck.java b/scm-core/src/main/java/sonia/scm/security/PermissionActionCheck.java
deleted file mode 100644
index 0e8815d2fe..0000000000
--- a/scm-core/src/main/java/sonia/scm/security/PermissionActionCheck.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright (c) 2014, 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.SecurityUtils;
-import org.apache.shiro.subject.Subject;
-
-import sonia.scm.ModelObject;
-
-/**
- *
- * @author Sebastian Sdorra
- * @param
- *
- * @since 2.0.0
- */
-public final class PermissionActionCheck
-{
-
- /**
- * Constructs ...
- *
- * @param typedAction
- */
- public PermissionActionCheck(String typedAction)
- {
- this.prefix = typedAction.concat(":");
- this.subject = SecurityUtils.getSubject();
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param id
- */
- public void check(String id)
- {
- subject.checkPermission(prefix.concat(id));
- }
-
- /**
- * Method description
- *
- *
- * @param item
- */
- public void check(T item)
- {
- subject.checkPermission(prefix.concat(item.getId()));
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param id
- *
- * @return
- */
- public boolean isPermitted(String id)
- {
- return subject.isPermitted(prefix.concat(id));
- }
-
- /**
- * Method description
- *
- *
- * @param item
- *
- * @return
- */
- public boolean isPermitted(T item)
- {
- return subject.isPermitted(prefix.concat(item.getId()));
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private final String prefix;
-
- /** Field description */
- private final Subject subject;
-}
diff --git a/scm-core/src/main/java/sonia/scm/security/PermissionCheck.java b/scm-core/src/main/java/sonia/scm/security/PermissionCheck.java
deleted file mode 100644
index 0f8c0beb3a..0000000000
--- a/scm-core/src/main/java/sonia/scm/security/PermissionCheck.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Copyright (c) 2014, 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.SecurityUtils;
-
-/**
- *
- * @author Sebastian Sdorra
- * @since 2.0.0
- */
-public final class PermissionCheck
-{
-
- /**
- * Constructs ...
- *
- *
- * @param permission
- */
- public PermissionCheck(String permission)
- {
- this.permission = permission;
- }
-
- //~--- methods --------------------------------------------------------------
-
- /**
- * Method description
- *
- */
- public void check()
- {
- SecurityUtils.getSubject().checkPermission(permission);
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @return
- */
- public boolean isPermitted()
- {
- return SecurityUtils.getSubject().isPermitted(permission);
- }
-
- //~--- fields ---------------------------------------------------------------
-
- /** Field description */
- private final String permission;
-}
diff --git a/scm-core/src/main/java/sonia/scm/user/User.java b/scm-core/src/main/java/sonia/scm/user/User.java
index 9ffec01c6f..69c5a5732f 100644
--- a/scm-core/src/main/java/sonia/scm/user/User.java
+++ b/scm-core/src/main/java/sonia/scm/user/User.java
@@ -35,6 +35,8 @@ package sonia.scm.user;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionObject;
+import com.github.sdorra.ssp.StaticPermissions;
import com.google.common.base.Objects;
import sonia.scm.BasicPropertiesAware;
@@ -54,9 +56,10 @@ import javax.xml.bind.annotation.XmlRootElement;
*
* @author Sebastian Sdorra
*/
+@StaticPermissions("user")
@XmlRootElement(name = "users")
@XmlAccessorType(XmlAccessType.FIELD)
-public class User extends BasicPropertiesAware implements Principal, ModelObject
+public class User extends BasicPropertiesAware implements Principal, ModelObject, PermissionObject
{
/** Field description */
diff --git a/scm-core/src/test/java/sonia/scm/repository/RepositoryPermissionsTest.java b/scm-core/src/test/java/sonia/scm/repository/RepositoryPermissionsTest.java
deleted file mode 100644
index 4457941c52..0000000000
--- a/scm-core/src/test/java/sonia/scm/repository/RepositoryPermissionsTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/**
- * Copyright (c) 2014, 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.repository;
-
-import com.github.sdorra.shiro.ShiroRule;
-import com.github.sdorra.shiro.SubjectAware;
-import java.util.function.Supplier;
-import org.apache.shiro.authz.UnauthorizedException;
-import org.junit.Test;
-import static org.junit.Assert.*;
-import org.junit.Rule;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import static org.mockito.Mockito.*;
-import org.mockito.runners.MockitoJUnitRunner;
-import sonia.scm.security.PermissionActionCheck;
-import sonia.scm.security.PermissionCheck;
-
-/**
- * Unit tests for {@link RepositoryPermissions}.
- *
- * @author Sebastian Sdorra
- */
-@RunWith(MockitoJUnitRunner.class)
-@SubjectAware(configuration = "classpath:sonia/scm/repository/repository-permissions.ini")
-public class RepositoryPermissionsTest {
-
- @Mock
- private Repository repository;
-
- /**
- * Shiro rule.
- */
- @Rule
- public ShiroRule shiro = new ShiroRule();
-
- /**
- * Test permission checks with id successful.
- */
- @Test
- @SubjectAware(username = "permitted", password = "secret")
- public void testPermissionCheckWithId() {
- assertPermissionCheckId(RepositoryPermissions::read);
- assertPermissionCheckId(RepositoryPermissions::write);
- assertPermissionCheckId(RepositoryPermissions::delete);
- assertPermissionCheckId(RepositoryPermissions::modify);
- assertPermissionCheckId(RepositoryPermissions::healthCheck);
- }
-
- /**
- * Test permission checks with id successful.
- */
- @Test
- @SubjectAware(username = "permitted", password = "secret")
- public void testPermissionActionCheck() {
- assertPermissionActionCheck(RepositoryPermissions::read);
- assertPermissionActionCheck(RepositoryPermissions::write);
- assertPermissionActionCheck(RepositoryPermissions::delete);
- assertPermissionActionCheck(RepositoryPermissions::modify);
- assertPermissionActionCheck(RepositoryPermissions::healthCheck);
- }
-
- @Test
- @SubjectAware(username = "notpermitted", password = "secret")
- public void testPermissionActionCheckWithoutRequired() {
- assertFailedPermissionActionCheck(RepositoryPermissions::read);
- assertFailedPermissionActionCheck(RepositoryPermissions::write);
- assertFailedPermissionActionCheck(RepositoryPermissions::delete);
- assertFailedPermissionActionCheck(RepositoryPermissions::modify);
- assertFailedPermissionActionCheck(RepositoryPermissions::healthCheck);
- }
-
- /**
- * Test permission checks with repository successful.
- */
- @Test
- @SubjectAware(username = "permitted", password = "secret")
- public void testPermissionCheckWithRepository() {
- assertPermissionCheckRepository(RepositoryPermissions::read);
- assertPermissionCheckRepository(RepositoryPermissions::write);
- assertPermissionCheckRepository(RepositoryPermissions::delete);
- assertPermissionCheckRepository(RepositoryPermissions::modify);
- assertPermissionCheckRepository(RepositoryPermissions::healthCheck);
- }
-
- /**
- * Test permission checks with id and without the required permissions.
- */
- @Test
- @SubjectAware(username = "notpermitted", password = "secret")
- public void testPermissionCheckWithIdAndWithoutRequiredPermissions() {
- assertFailedPermissionCheckId(RepositoryPermissions::read);
- assertFailedPermissionCheckId(RepositoryPermissions::write);
- assertFailedPermissionCheckId(RepositoryPermissions::delete);
- assertFailedPermissionCheckId(RepositoryPermissions::modify);
- assertFailedPermissionCheckId(RepositoryPermissions::healthCheck);
- }
-
- /**
- * Tests permission checks with repository and without the required permissions.
- */
- @Test
- @SubjectAware(username = "notpermitted", password = "secret")
- public void testPermissionCheckWithRepositoryAndWithoutRequiredPermissions() {
- assertFailedPermissionCheckRepository(RepositoryPermissions::read);
- assertFailedPermissionCheckRepository(RepositoryPermissions::write);
- assertFailedPermissionCheckRepository(RepositoryPermissions::delete);
- assertFailedPermissionCheckRepository(RepositoryPermissions::modify);
- assertFailedPermissionCheckRepository(RepositoryPermissions::healthCheck);
- }
-
- private void assertFailedPermissionCheckRepository(RepositoryPermissionChecker checker) {
- when(repository.getId()).thenReturn("abc");
- assertFailedPermissionCheck(checker.get(repository));
- }
-
- private void assertFailedPermissionCheckId(RepositoryPermissionChecker checker) {
- assertFailedPermissionCheck(checker.get("abc"));
- }
-
- private void assertFailedPermissionCheck(PermissionCheck check) {
- assertNotNull(check);
- assertFalse(check.isPermitted());
- boolean fail = false;
- try {
- check.check();
- }
- catch (UnauthorizedException ex) {
- fail = true;
- }
- assertTrue(fail);
- }
-
- private void assertPermissionCheckRepository(RepositoryPermissionChecker checker) {
- when(repository.getId()).thenReturn("abc");
- assertPermissionCheck(checker.get(repository));
- }
-
- private void assertPermissionCheckId(RepositoryPermissionChecker checker) {
- assertPermissionCheck(checker.get("abc"));
- }
-
- private void assertPermissionCheck(PermissionCheck check) {
- assertNotNull(check);
- assertTrue(check.isPermitted());
- check.check();
- }
-
- private void assertPermissionActionCheck(Supplier> supplier) {
- assertPermissionActionCheck(supplier.get());
- }
-
- private void assertFailedPermissionActionCheck(Supplier> supplier) {
- assertFailedPermissionActionCheck(supplier.get());
- }
-
- private void assertFailedPermissionActionCheck(PermissionActionCheck check) {
- assertNotNull(check);
- assertFalse(check.isPermitted("abc"));
- boolean fail = false;
- try {
- check.check("abc");
- }
- catch (UnauthorizedException ex) {
- fail = true;
- }
- assertTrue(fail);
- fail = false;
- when(repository.getId()).thenReturn("abc");
- assertFalse(check.isPermitted(repository));
- try {
- check.check(repository);
- }
- catch (UnauthorizedException ex) {
- fail = true;
- }
- assertTrue(fail);
- }
-
- private void assertPermissionActionCheck(PermissionActionCheck check) {
- assertNotNull(check);
- assertTrue(check.isPermitted("abc"));
- check.check("abc");
- when(repository.getId()).thenReturn("abc");
- assertTrue(check.isPermitted(repository));
- check.check(repository);
- }
-
- @FunctionalInterface
- private static interface RepositoryPermissionChecker {
-
- public PermissionCheck get(T type);
-
- }
-
-}
diff --git a/scm-webapp/src/main/java/sonia/scm/plugin/MultiParentClassLoader.java b/scm-webapp/src/main/java/sonia/scm/plugin/MultiParentClassLoader.java
index ebd8b6e24e..5881652ec4 100644
--- a/scm-webapp/src/main/java/sonia/scm/plugin/MultiParentClassLoader.java
+++ b/scm-webapp/src/main/java/sonia/scm/plugin/MultiParentClassLoader.java
@@ -74,7 +74,7 @@ public class MultiParentClassLoader extends ClassLoader
public MultiParentClassLoader(Collection extends ClassLoader> parents)
{
super(null);
- this.parents = new CopyOnWriteArrayList<>(parents);
+ this.parents = new CopyOnWriteArrayList(parents);
}
//~--- get methods ----------------------------------------------------------
diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
index 350052f5ac..daee5f42b3 100644
--- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
+++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
@@ -35,6 +35,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionActionCheck;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@@ -53,7 +54,6 @@ import sonia.scm.SCMContextProvider;
import sonia.scm.Type;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.security.KeyGenerator;
-import sonia.scm.security.PermissionActionCheck;
import sonia.scm.util.AssertUtil;
import sonia.scm.util.CollectionAppender;
import sonia.scm.util.HttpUtil;
diff --git a/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java b/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java
index 302d92a79e..26f674a5b5 100644
--- a/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java
+++ b/scm-webapp/src/main/java/sonia/scm/repository/HealthChecker.java
@@ -33,6 +33,7 @@ package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionActionCheck;
import com.google.common.collect.ImmutableList;
import com.google.inject.Inject;
@@ -43,7 +44,6 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.Set;
-import sonia.scm.security.PermissionActionCheck;
/**
*
@@ -91,7 +91,7 @@ public final class HealthChecker
public void check(String id)
throws RepositoryNotFoundException, RepositoryException, IOException
{
- RepositoryPermissions.healthCheck(id);
+ RepositoryPermissions.healthCheck(id).check();
Repository repository = repositoryManager.get(id);
@@ -116,7 +116,7 @@ public final class HealthChecker
public void check(Repository repository)
throws RepositoryException, IOException
{
- RepositoryPermissions.healthCheck(repository);
+ RepositoryPermissions.healthCheck(repository).check();
doCheck(repository);
}
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 f1d6a67e90..48ea159c83 100644
--- a/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java
+++ b/scm-webapp/src/main/java/sonia/scm/user/DefaultUserManager.java
@@ -35,12 +35,10 @@ package sonia.scm.user;
//~--- non-JDK imports --------------------------------------------------------
+import com.github.sdorra.ssp.PermissionActionCheck;
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import org.apache.shiro.SecurityUtils;
-import org.apache.shiro.subject.Subject;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,12 +47,9 @@ 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;
//~--- JDK imports ------------------------------------------------------------
@@ -99,10 +94,6 @@ public class DefaultUserManager extends AbstractUserManager
/**
* Constructs ...
*
-<<<<<<< mine
-=======
- *
->>>>>>> theirs
* @param userDAO
*/
@Inject
@@ -164,17 +155,7 @@ public class DefaultUserManager extends AbstractUserManager
logger.info("create user {} of type {}", user.getName(), user.getType());
}
- Subject subject = SecurityUtils.getSubject();
-
- if (!subject.hasRole(Role.USER))
- {
- throw new ScmSecurityException("user is not authenticated");
- }
-
- if (!subject.hasRole(Role.ADMIN))
- {
- throw new ScmSecurityException("admin account is required");
- }
+ UserPermissions.create().check();
if (userDAO.contains(user.getName()))
{
@@ -205,9 +186,8 @@ public class DefaultUserManager extends AbstractUserManager
logger.info("delete user {} of type {}", user.getName(), user.getType());
}
- SecurityUtil.assertIsAdmin();
-
String name = user.getName();
+ UserPermissions.delete(name).check();
if (userDAO.contains(name))
{
@@ -250,28 +230,13 @@ public class DefaultUserManager extends AbstractUserManager
@Override
public void modify(User user) throws UserException, IOException
{
+ String name = user.getName();
if (logger.isInfoEnabled())
{
logger.info("modify user {} of type {}", user.getName(), user.getType());
}
-
- Subject subject = SecurityUtils.getSubject();
-
- 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");
- }
-
- String name = user.getName();
+ UserPermissions.modify(user).check();
User oldUser = userDAO.get(name);
if (oldUser != null)
@@ -305,8 +270,7 @@ public class DefaultUserManager extends AbstractUserManager
logger.info("refresh user {} of type {}", user.getName(), user.getType());
}
- SecurityUtil.assertIsAdmin();
-
+ UserPermissions.read(user).check();
User fresh = userDAO.get(user.getName());
if (fresh == null)
@@ -333,24 +297,23 @@ public class DefaultUserManager extends AbstractUserManager
logger.debug("search user with query {}", searchRequest.getQuery());
}
- return SearchUtil.search(searchRequest, userDAO.getAll(),
- new TransformFilter()
- {
+ final PermissionActionCheck check = UserPermissions.read();
+ return SearchUtil.search(searchRequest, userDAO.getAll(), new TransformFilter() {
@Override
public User accept(User user)
{
User result = null;
-
- if (SearchUtil.matchesOne(searchRequest, user.getName(),
- user.getDisplayName(), user.getMail()))
- {
+ if (check.isPermitted(user) && matches(searchRequest, user)) {
result = user.clone();
}
-
return result;
}
});
}
+
+ private boolean matches(SearchRequest searchRequest, User user) {
+ return SearchUtil.matchesOne(searchRequest, user.getName(), user.getDisplayName(), user.getMail());
+ }
//~--- get methods ----------------------------------------------------------
@@ -365,8 +328,8 @@ public class DefaultUserManager extends AbstractUserManager
@Override
public User get(String id)
{
-
- // SecurityUtil.assertIsAdmin(scurityContextProvider);
+ UserPermissions.read().check(id);
+
User user = userDAO.get(id);
if (user != null)
@@ -400,17 +363,16 @@ public class DefaultUserManager extends AbstractUserManager
@Override
public Collection getAll(Comparator comparator)
{
- SecurityUtil.assertIsAdmin();
+ List users = new ArrayList<>();
- List users = new ArrayList();
-
- for (User user : userDAO.getAll())
- {
- users.add(user.clone());
+ PermissionActionCheck check = UserPermissions.read();
+ for (User user : userDAO.getAll()) {
+ if (check.isPermitted(user)) {
+ users.add(user.clone());
+ }
}
- if (comparator != null)
- {
+ if (comparator != null) {
Collections.sort(users, comparator);
}
@@ -429,18 +391,17 @@ public class DefaultUserManager extends AbstractUserManager
* @return
*/
@Override
- public Collection getAll(Comparator comaparator, int start,
- int limit)
- {
- SecurityUtil.assertIsAdmin();
-
+ public Collection getAll(Comparator comaparator, int start, int limit) {
+ final PermissionActionCheck check = UserPermissions.read();
return Util.createSubCollection(userDAO.getAll(), comaparator,
new CollectionAppender()
{
@Override
public void append(Collection collection, User item)
{
- collection.add(item.clone());
+ if (check.isPermitted(item)) {
+ collection.add(item.clone());
+ }
}
}, start, limit);
}