diff --git a/ccm-core/src/main/java/org/libreccm/core/Permission.java b/ccm-core/src/main/java/org/libreccm/core/Permission.java
index 5e44c3ff4..7428ac437 100644
--- a/ccm-core/src/main/java/org/libreccm/core/Permission.java
+++ b/ccm-core/src/main/java/org/libreccm/core/Permission.java
@@ -41,6 +41,8 @@ import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
/**
+ * Represents a {@link Privilege} granted to a {@link Subject} on an object or
+ * all objects.
*
* @author Jens Pelzetter
*/
@@ -81,35 +83,66 @@ public class Permission implements Serializable {
private static final long serialVersionUID = -2368935232499907547L;
+ /**
+ * The database id of the permission.
+ */
@Id
@Column(name = "permission_id")
@GeneratedValue(strategy = GenerationType.AUTO)
@XmlElement(name = "permission-id", namespace = CORE_XML_NS)
private long permissionId;
+ /**
+ * The {@link Subject} (a {@link User} or a {@link Group}) to which the
+ * permission is granted. If the permission is granted to a {@link Group} a
+ * {@link User}s in that have the permission.
+ */
@ManyToOne
@JoinColumn(name = "grantee_id")
private Subject grantee;
+ /**
+ * The {@link Privilege} granted by this {@code Permission}.
+ */
@OneToOne
@JoinColumn(name = "granted_privilege_id")
@XmlElement(name = "privilege", namespace = CORE_XML_NS)
private Privilege grantedPrivilege;
+ /**
+ * The {@link CcmObject} on which the permission is granted. If the the
+ * {@code object} is {@code null} the permission is granted for
+ * all objects.
+ */
@ManyToOne
@JoinColumn(name = "object_id")
private CcmObject object;
+ /**
+ * The {@link User} which created this {@code Permission}. The property can
+ * be {@code null} if this {@code Permission} was created by a system
+ * process.
+ */
@ManyToOne
@JoinColumn(name = "creation_user_id")
@XmlElement(name = "creation-user", namespace = CORE_XML_NS)
private User creationUser;
+ /**
+ * The date and time on which this {@code Permission} was created. This
+ * property can be {@code null} if this {@code Permission} was created by a
+ * system process.
+ */
@Column(name = "creation_date")
@Temporal(TemporalType.TIMESTAMP)
@XmlElement(name = "creation-date", namespace = CORE_XML_NS)
private Date creationDate;
+ /**
+ * The IP of the system from which this {@code Permission} was created. This
+ * property can be {@code null} if this {@code Permission} was created by a
+ * system process.
+ */
@Column(name = "creation_ip")
@XmlElement(name = "creation-ip", namespace = CORE_XML_NS)
private String creationIp;
diff --git a/ccm-core/src/main/java/org/libreccm/core/UserRepository.java b/ccm-core/src/main/java/org/libreccm/core/UserRepository.java
index 38b281191..0159ed425 100644
--- a/ccm-core/src/main/java/org/libreccm/core/UserRepository.java
+++ b/ccm-core/src/main/java/org/libreccm/core/UserRepository.java
@@ -21,6 +21,7 @@ package org.libreccm.core;
import java.util.List;
import javax.enterprise.context.RequestScoped;
+import javax.inject.Inject;
import javax.persistence.TypedQuery;
/**
@@ -30,6 +31,9 @@ import javax.persistence.TypedQuery;
@RequestScoped
public class UserRepository extends AbstractEntityRepository {
+ @Inject
+ private transient PrivilegeRepository privilegeRepository;
+
@Override
public Class getEntityClass() {
return User.class;
@@ -50,7 +54,17 @@ public class UserRepository extends AbstractEntityRepository {
* @return The internal system user.
*/
public User retrieveSystemUser() {
- throw new UnsupportedOperationException();
+ final User systemUser = new User();
+ systemUser.setScreenName("system");
+
+ final Privilege adminPrivilege = privilegeRepository.retrievePrivilege(
+ "admin");
+ final Permission systemPermission = new Permission();
+ systemPermission.setGrantee(systemUser);
+ systemPermission.setGrantedPrivilege(adminPrivilege);
+ systemUser.addGrantedPermission(systemPermission);
+
+ return systemUser;
}
/**
@@ -63,7 +77,7 @@ public class UserRepository extends AbstractEntityRepository {
* public user.
*/
public User retrievePublicUser() {
- throw new UnsupportedOperationException();
+ return findByScreenName("public-user");
}
public User findByScreenName(final String screenname) {
diff --git a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
index 0e6e89cd1..c74607693 100644
--- a/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
+++ b/ccm-core/src/test/java/org/libreccm/core/DatasetsTest.java
@@ -54,6 +54,9 @@ public class DatasetsTest extends DatasetsVerifier {
"/datasets/org/libreccm/core/GroupRepositoryTest/after-delete.json",
"/datasets/org/libreccm/core/GroupRepositoryTest/after-save-changed.json",
"/datasets/org/libreccm/core/GroupRepositoryTest/after-save-new.json",
+ "/datasets/org/libreccm/core/PermissionManagerTest/after-grant.json",
+ "/datasets/org/libreccm/core/PermissionManagerTest/after-revoke.json",
+ "/datasets/org/libreccm/core/PermissionManagerTest/data.json",
"/datasets/org/libreccm/core/PermissionRepositoryTest/after-save-changed.json",
"/datasets/org/libreccm/core/PermissionRepositoryTest/after-save-new.json",
"/datasets/org/libreccm/core/PermissionRepositoryTest/after-delete.json",
diff --git a/ccm-core/src/test/java/org/libreccm/core/PermissionManagerTest.java b/ccm-core/src/test/java/org/libreccm/core/PermissionManagerTest.java
new file mode 100644
index 000000000..a5450bdd0
--- /dev/null
+++ b/ccm-core/src/test/java/org/libreccm/core/PermissionManagerTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 LibreCCM Foundation.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+package org.libreccm.core;
+
+import java.io.File;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.container.test.api.ShouldThrowException;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.arquillian.junit.InSequence;
+import org.jboss.arquillian.persistence.PersistenceTest;
+import org.jboss.arquillian.persistence.UsingDataSet;
+import org.jboss.arquillian.transaction.api.annotation.TransactionMode;
+import org.jboss.arquillian.transaction.api.annotation.Transactional;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.resolver.api.maven.Maven;
+import org.jboss.shrinkwrap.resolver.api.maven.PomEquippedResolveStage;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.libreccm.tests.categories.IntegrationTest;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+@Category(IntegrationTest.class)
+@RunWith(Arquillian.class)
+@PersistenceTest
+@Transactional(TransactionMode.COMMIT)
+public class PermissionManagerTest {
+
+ public PermissionManagerTest() {
+ }
+
+ @BeforeClass
+ public static void setUpClass() {
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ }
+
+ @Before
+ public void setUp() {
+ }
+
+ @After
+ public void tearDown() {
+ }
+
+ // TODO add test methods here.
+ // The methods must be annotated with annotation @Test. For example:
+ //
+ // @Test
+ // public void hello() {}
+ @Deployment
+ public static WebArchive createDeployment() {
+ final PomEquippedResolveStage pom = Maven
+ .resolver()
+ .loadPomFromFile("pom.xml");
+ final PomEquippedResolveStage dependencies = pom.
+ importCompileAndRuntimeDependencies();
+ final File[] libs = dependencies.resolve().withTransitivity().asFile();
+
+ for (File lib : libs) {
+ System.err.printf("Adding file '%s' to test archive...%n",
+ lib.getName());
+ }
+
+ return ShrinkWrap
+ .create(WebArchive.class,
+ String.format("LibreCCM-%s.war",
+ PermissionManagerTest.class.getName()))
+ .addPackage(User.class.getPackage())
+ .addPackage(org.libreccm.web.Application.class.getPackage())
+ .addPackage(org.libreccm.categorization.Category.class.
+ getPackage())
+ .addPackage(org.libreccm.l10n.LocalizedString.class.getPackage()).
+ addPackage(org.libreccm.jpa.EntityManagerProducer.class
+ .getPackage())
+ .addPackage(org.libreccm.jpa.utils.MimeTypeConverter.class
+ .getPackage())
+ .addPackage(org.libreccm.testutils.EqualsVerifier.class.
+ getPackage())
+ .addPackage(org.libreccm.tests.categories.IntegrationTest.class
+ .getPackage())
+ .addAsLibraries(libs)
+ .addAsResource("test-persistence.xml",
+ "META-INF/persistence.xml")
+ .addAsWebInfResource("test-web.xml", "WEB-INF/web.xml")
+ .addAsWebInfResource(EmptyAsset.INSTANCE, "WEB-INF/beans.xml");
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @InSequence(110)
+ public void isPermittedGrantedByAdminPrivilege() {
+ fail();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @InSequence(120)
+ public void isPermittedGrantedByDirectPermission() {
+ fail();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @InSequence(130)
+ public void isPermittedGrantedByGroup() {
+ fail();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @InSequence(140)
+ public void isPermittedPublicUserGranted() {
+ fail();
+ }
+
+ @Test
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @InSequence(150)
+ public void isPermittedPublicUserDenied() {
+ fail();
+ }
+
+ @Test(expected = UnauthorizedAcccessException.class)
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @ShouldThrowException(UnauthorizedAcccessException.class)
+ @InSequence(210)
+ public void checkPermittedGrantedByAdminPrivilege() {
+ fail();
+ }
+
+ @Test(expected = UnauthorizedAcccessException.class)
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @ShouldThrowException(UnauthorizedAcccessException.class)
+ @InSequence(220)
+ public void checkPermittedGrantedByDirectPermission() {
+ fail();
+ }
+
+ @Test(expected = UnauthorizedAcccessException.class)
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @ShouldThrowException(UnauthorizedAcccessException.class)
+ @InSequence(230)
+ public void checkPermittedGrantedByGroup() {
+ fail();
+ }
+
+ @Test(expected = UnauthorizedAcccessException.class)
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @ShouldThrowException(UnauthorizedAcccessException.class)
+ @InSequence(240)
+ public void checkPermittedPublicUserGranted() {
+ fail();
+ }
+
+ @Test(expected = UnauthorizedAcccessException.class)
+ @UsingDataSet("datasets/org/libreccm/core/PermissionManagerTest/"
+ + "data.json")
+ @ShouldThrowException(UnauthorizedAcccessException.class)
+ @InSequence(250)
+ public void checkPermittedPublicUserDenied() {
+ fail();
+ }
+}
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-grant.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-grant.json
new file mode 100644
index 000000000..cfa6ac97e
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-grant.json
@@ -0,0 +1,306 @@
+{
+ "ccm_objects":
+ [
+ {
+ "object_id": -10,
+ "display_name": "Test Object 1"
+ },
+ {
+ "object_id": -20,
+ "display_name": "Test Object 2"
+ },
+ {
+ "object_id": -30,
+ "display_name": "Test Object 3"
+ },
+ {
+ "object_id": -40,
+ "display_name": "Test Object 4"
+ },
+ {
+ "object_id": -50,
+ "display_name": "Test Object 5"
+ },
+ {
+ "object_id": -60,
+ "display_name": "Test Object 6"
+ },
+ {
+ "object_id": -70,
+ "display_name": "Test Object 7"
+ },
+ {
+ "object_id": -80,
+ "display_name": "Test Object 8"
+ }
+ ],
+ "ccm_privileges":
+ [
+ {
+ "privilege_id": -10,
+ "label": "admin"
+ },
+ {
+ "privilege_id": -20,
+ "label": "read"
+ },
+ {
+ "privilege_id": -30,
+ "label": "write"
+ }
+ ],
+ "subjects":
+ [
+ {
+ "subject_id": -1
+ },
+ {
+ "subject_id": -2
+ },
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "webmaster",
+ "given_name": "webmaster",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "webmaster",
+ "subject_id": -1
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "public-user",
+ "given_name": "public-user",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "public-user",
+ "subject_id": -2
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Doe",
+ "given_name": "John",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "password_reset_required": false,
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "jdoe",
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "password": "1c9626af429a6291766d15cbfb38689bd8d49450520765973de70aecaf644b7d4fda711266ba9ec8fb6df30c8ab391d40330829aa85adf371bcde6b4c9bc01e6",
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "subject_id": -50
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "users",
+ "subject_id": -30
+ },
+ {
+ "name": "authors",
+ "subject_id": -40
+ }
+ ],
+ "group_memberships":
+ [
+ {
+ "membership_id": -10,
+ "group_subject_id": -40,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -20,
+ "group_subject_id": -40,
+ "user_subject_id": -50
+ },
+ {
+ "membership_id": -30,
+ "group_subject_id": -30,
+ "user_subject_id": -2
+ },
+ {
+ "membership_id": -40,
+ "group_subject_id": -30,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -50,
+ "group_subject_id": -30,
+ "user_subject_id": -50
+ }
+ ],
+ "user_email_addresses":
+ [
+ {
+ "user_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "user_id": -50,
+ "email_address": "max.mustermann@example.com",
+ "bouncing": false,
+ "verified": true
+ }
+ ],
+ "permissions":
+ [
+ {
+ "permission_id": -10,
+ "grantee_id": -1,
+ "granted_privilege_id": -10
+ },
+ {
+ "permission_id": -20,
+ "grantee_id": -2,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -30,
+ "grantee_id": -10,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -40,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -50,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -60,
+ "grantee_id": -50,
+ "object_id": -60,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -70,
+ "grantee_id": -50,
+ "object_id": -60,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -80,
+ "grantee_id": -30,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -90,
+ "grantee_id": -30,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -100,
+ "grantee_id": -30,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -110,
+ "grantee_id": -30,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -120,
+ "grantee_id": -30,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -130,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -140,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -150,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -160,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -170,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -180,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -190,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -200,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -220,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -230,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -30
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-revoke.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-revoke.json
new file mode 100644
index 000000000..487a2030b
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/after-revoke.json
@@ -0,0 +1,324 @@
+{
+ "ccm_objects":
+ [
+ {
+ "object_id": -10,
+ "display_name": "Test Object 1"
+ },
+ {
+ "object_id": -20,
+ "display_name": "Test Object 2"
+ },
+ {
+ "object_id": -30,
+ "display_name": "Test Object 3"
+ },
+ {
+ "object_id": -40,
+ "display_name": "Test Object 4"
+ },
+ {
+ "object_id": -50,
+ "display_name": "Test Object 5"
+ },
+ {
+ "object_id": -60,
+ "display_name": "Test Object 6"
+ },
+ {
+ "object_id": -70,
+ "display_name": "Test Object 7"
+ },
+ {
+ "object_id": -80,
+ "display_name": "Test Object 8"
+ }
+ ],
+ "ccm_privileges":
+ [
+ {
+ "privilege_id": -10,
+ "label": "admin"
+ },
+ {
+ "privilege_id": -20,
+ "label": "read"
+ },
+ {
+ "privilege_id": -30,
+ "label": "write"
+ }
+ ],
+ "subjects":
+ [
+ {
+ "subject_id": -1
+ },
+ {
+ "subject_id": -2
+ },
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "webmaster",
+ "given_name": "webmaster",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "webmaster",
+ "subject_id": -1
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "public-user",
+ "given_name": "public-user",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "public-user",
+ "subject_id": -2
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Doe",
+ "given_name": "John",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "password_reset_required": false,
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "jdoe",
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "password": "1c9626af429a6291766d15cbfb38689bd8d49450520765973de70aecaf644b7d4fda711266ba9ec8fb6df30c8ab391d40330829aa85adf371bcde6b4c9bc01e6",
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "subject_id": -50
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "users",
+ "subject_id": -30
+ },
+ {
+ "name": "authors",
+ "subject_id": -40
+ }
+ ],
+ "group_memberships":
+ [
+ {
+ "membership_id": -10,
+ "group_subject_id": -40,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -20,
+ "group_subject_id": -40,
+ "user_subject_id": -50
+ },
+ {
+ "membership_id": -30,
+ "group_subject_id": -30,
+ "user_subject_id": -2
+ },
+ {
+ "membership_id": -40,
+ "group_subject_id": -30,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -50,
+ "group_subject_id": -30,
+ "user_subject_id": -50
+ }
+ ],
+ "user_email_addresses":
+ [
+ {
+ "user_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "user_id": -50,
+ "email_address": "max.mustermann@example.com",
+ "bouncing": false,
+ "verified": true
+ }
+ ],
+ "permissions":
+ [
+ {
+ "permission_id": -10,
+ "grantee_id": -1,
+ "granted_privilege_id": -10
+ },
+ {
+ "permission_id": -20,
+ "grantee_id": -2,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -30,
+ "grantee_id": -10,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -40,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -50,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -60,
+ "grantee_id": -50,
+ "object_id": -60,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -70,
+ "grantee_id": -50,
+ "object_id": -60,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -80,
+ "grantee_id": -30,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -90,
+ "grantee_id": -30,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -100,
+ "grantee_id": -30,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -110,
+ "grantee_id": -30,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -120,
+ "grantee_id": -30,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -130,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -140,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -150,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -160,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -170,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -180,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -190,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -200,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -220,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -230,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -240,
+ "grantee_id": -10,
+ "object_id": -60,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -250,
+ "grantee_id": -50,
+ "object_id": -70,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -260,
+ "grantee_id": -50,
+ "object_id": -70,
+ "granted_privilege_id": -30
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/data.json b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/data.json
new file mode 100644
index 000000000..e0e3f3b8d
--- /dev/null
+++ b/ccm-core/src/test/resources/datasets/org/libreccm/core/PermissionManagerTest/data.json
@@ -0,0 +1,312 @@
+{
+ "ccm_objects":
+ [
+ {
+ "object_id": -10,
+ "display_name": "Test Object 1"
+ },
+ {
+ "object_id": -20,
+ "display_name": "Test Object 2"
+ },
+ {
+ "object_id": -30,
+ "display_name": "Test Object 3"
+ },
+ {
+ "object_id": -40,
+ "display_name": "Test Object 4"
+ },
+ {
+ "object_id": -50,
+ "display_name": "Test Object 5"
+ },
+ {
+ "object_id": -60,
+ "display_name": "Test Object 6"
+ },
+ {
+ "object_id": -70,
+ "display_name": "Test Object 7"
+ },
+ {
+ "object_id": -80,
+ "display_name": "Test Object 8"
+ }
+ ],
+ "ccm_privileges":
+ [
+ {
+ "privilege_id": -10,
+ "label": "admin"
+ },
+ {
+ "privilege_id": -20,
+ "label": "read"
+ },
+ {
+ "privilege_id": -30,
+ "label": "write"
+ }
+ ],
+ "subjects":
+ [
+ {
+ "subject_id": -1
+ },
+ {
+ "subject_id": -2
+ },
+ {
+ "subject_id": -10
+ },
+ {
+ "subject_id": -30
+ },
+ {
+ "subject_id": -40
+ },
+ {
+ "subject_id": -50
+ }
+ ],
+ "ccm_users":
+ [
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "webmaster",
+ "given_name": "webmaster",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "webmaster",
+ "subject_id": -1
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "public-user",
+ "given_name": "public-user",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "public-user",
+ "subject_id": -2
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Doe",
+ "given_name": "John",
+ "password": "C+o2w6mp+eLrbluMEgKMVSdP50A9BMethXN8R3yihtkbzt7WfWsde2nmq/t5gq6im3J8i3jw4Y3YrKHou8JQ2A==",
+ "password_reset_required": false,
+ "salt": "Fu8FPgqAal4GZp1hDjkOB+t6ITRCcO7HBoN5Xqf29UnVj5NUdUFZRTyKYMBEx6JmZGmHcMDG9OGVCKcEM9oyScSRreJs4B51wM44NM6KeRwbCf+VhBn14DkBrl40ygraNf+AJacKpMyCpFI0O/Am7mMDWL4flskBsylkxaQn3vKfzgN5MVG2szW//I6Q6YEH9AuL8LauS6fKaVynMzzu3xzD8Hjqvvlnzym898eom2lqScPfg5g4e8Ww13HCHAYe6twupAW/BjUNax5HSioEisZN/P1UGrde8uFEj+hbbavrWYZuilPuEu25+/98jyXx6542agqrWN8j0SFYcIyOgA==",
+ "screen_name": "jdoe",
+ "subject_id": -10
+ },
+ {
+ "banned": false,
+ "hash_algorithm": "SHA-512",
+ "family_name": "Mustermann",
+ "given_name": "Max",
+ "password": "1c9626af429a6291766d15cbfb38689bd8d49450520765973de70aecaf644b7d4fda711266ba9ec8fb6df30c8ab391d40330829aa85adf371bcde6b4c9bc01e6",
+ "password_reset_required": false,
+ "salt": "fjiajhigafgapoa",
+ "screen_name": "mmuster",
+ "subject_id": -50
+ }
+ ],
+ "ccm_groups":
+ [
+ {
+ "name": "users",
+ "subject_id": -30
+ },
+ {
+ "name": "authors",
+ "subject_id": -40
+ }
+ ],
+ "group_memberships":
+ [
+ {
+ "membership_id": -10,
+ "group_subject_id": -40,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -20,
+ "group_subject_id": -40,
+ "user_subject_id": -50
+ },
+ {
+ "membership_id": -30,
+ "group_subject_id": -30,
+ "user_subject_id": -2
+ },
+ {
+ "membership_id": -40,
+ "group_subject_id": -30,
+ "user_subject_id": -10
+ },
+ {
+ "membership_id": -50,
+ "group_subject_id": -30,
+ "user_subject_id": -50
+ }
+ ],
+ "user_email_addresses":
+ [
+ {
+ "user_id": -10,
+ "email_address": "john.doe@example.com",
+ "bouncing": false,
+ "verified": true
+ },
+ {
+ "user_id": -50,
+ "email_address": "max.mustermann@example.com",
+ "bouncing": false,
+ "verified": true
+ }
+ ],
+ "permissions":
+ [
+ {
+ "permission_id": -10,
+ "grantee_id": -1,
+ "granted_privilege_id": -10
+ },
+ {
+ "permission_id": -20,
+ "grantee_id": -2,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -30,
+ "grantee_id": -10,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -40,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -50,
+ "grantee_id": -50,
+ "object_id": -50,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -60,
+ "grantee_id": -50,
+ "object_id": -60,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -80,
+ "grantee_id": -30,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -90,
+ "grantee_id": -30,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -100,
+ "grantee_id": -30,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -110,
+ "grantee_id": -30,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -120,
+ "grantee_id": -30,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -130,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -140,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -150,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -160,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -170,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -180,
+ "grantee_id": -40,
+ "object_id": -10,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -190,
+ "grantee_id": -40,
+ "object_id": -20,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -200,
+ "grantee_id": -40,
+ "object_id": -30,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -220,
+ "grantee_id": -40,
+ "object_id": -40,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -230,
+ "grantee_id": -40,
+ "object_id": -80,
+ "granted_privilege_id": -30
+ },
+ {
+ "permission_id": -250,
+ "grantee_id": -50,
+ "object_id": -70,
+ "granted_privilege_id": -20
+ },
+ {
+ "permission_id": -260,
+ "grantee_id": -50,
+ "object_id": -70,
+ "granted_privilege_id": -30
+ }
+ ]
+}
\ No newline at end of file