diff --git a/ccm-core/src/main/java/org/libreccm/api/AdminApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
similarity index 74%
rename from ccm-core/src/main/java/org/libreccm/api/AdminApi.java
rename to ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
index 9e9b7b837..4c346312a 100644
--- a/ccm-core/src/main/java/org/libreccm/api/AdminApi.java
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/AdminApi.java
@@ -3,11 +3,11 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
-package org.libreccm.api;
+package org.libreccm.api.admin;
-import org.libreccm.security.GroupsApi;
-import org.libreccm.security.RolesApi;
-import org.libreccm.security.UsersApi;
+import org.libreccm.api.admin.security.GroupsApi;
+import org.libreccm.api.admin.security.RolesApi;
+import org.libreccm.api.admin.security.UsersApi;
import java.util.HashSet;
import java.util.Set;
@@ -15,6 +15,10 @@ import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
+import org.libreccm.api.CorsFilter;
+import org.libreccm.api.DefaultResponseHeaders;
+import org.libreccm.api.PreflightRequestFilter;
+
/**
*
* @author Jens Pelzetter
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/package-info.java b/ccm-core/src/main/java/org/libreccm/api/admin/package-info.java
new file mode 100644
index 000000000..eee9b1305
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 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
+ */
+/**
+ * RESTful API for administration tasks.
+ */
+package org.libreccm.api.admin;
diff --git a/ccm-core/src/main/java/org/libreccm/security/GroupsApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/GroupsApi.java
similarity index 89%
rename from ccm-core/src/main/java/org/libreccm/security/GroupsApi.java
rename to ccm-core/src/main/java/org/libreccm/api/admin/security/GroupsApi.java
index e91898a53..f02e619d5 100644
--- a/ccm-core/src/main/java/org/libreccm/security/GroupsApi.java
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/GroupsApi.java
@@ -15,22 +15,21 @@
* 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.security;
+ */package org.libreccm.api.admin.security;
+import org.libreccm.api.admin.security.dto.GroupData;
+import org.libreccm.api.admin.security.dto.GroupUserMembership;
+import org.libreccm.api.admin.security.dto.PartyRoleMembership;
+import org.libreccm.api.dto.ListView;
import org.libreccm.core.CoreConstants;
import org.libreccm.core.api.ExtractedIdentifier;
import org.libreccm.core.api.IdentifierExtractor;
-import org.libreccm.core.api.JsonArrayCollector;
import java.net.URI;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -46,6 +45,19 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.Group;
+import org.libreccm.security.GroupManager;
+import org.libreccm.security.GroupRepository;
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.security.Role;
+import org.libreccm.security.RoleManager;
+import org.libreccm.security.RoleRepository;
+import org.libreccm.security.User;
+import org.libreccm.security.UserRepository;
+
+import java.util.stream.Collectors;
+
/**
*
* @author Jens Pelzetter
@@ -78,27 +90,19 @@ public class GroupsApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonObject getGroups(
+ public ListView getGroups(
@QueryParam("limit") @DefaultValue("20") final int limit,
@QueryParam("offset") @DefaultValue("0") final int offset
) {
final long count = groupRepository.countAll();
final List groups = groupRepository.findAll();
- return Json
- .createObjectBuilder()
- .add("count", count)
- .add("limit", limit)
- .add("offset", offset)
- .add(
- "groups",
- groups
- .stream()
- .map(Group::buildJson)
- .map(JsonObjectBuilder::build)
- .collect(new JsonArrayCollector())
- )
- .build();
+ return new ListView<>(
+ groups.stream().map(GroupData::new).collect(Collectors.toList()),
+ count,
+ limit,
+ offset
+ );
}
@GET
@@ -107,10 +111,10 @@ public class GroupsApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonObject getGroup(
+ public GroupData getGroup(
@PathParam("groupIdentifier") final String identifierParam
) {
- return findGroup(identifierParam).toJson();
+ return new GroupData(findGroup(identifierParam));
}
@POST
@@ -119,15 +123,15 @@ public class GroupsApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public Response addGroup(final JsonObject groupData) {
- if (groupData.isNull("name")
- || groupData.getString("name").matches("\\s*")) {
+ public Response addGroup(final GroupData groupData) {
+ if (groupData.getName() == null
+ || groupData.getName().matches("\\s*")) {
return Response
.status(Response.Status.BAD_REQUEST)
.entity("Name of new group is missing.")
.build();
}
- final String name = groupData.getString("name");
+ final String name = groupData.getName();
if (groupRepository.findByName(name).isPresent()) {
return Response
@@ -161,15 +165,15 @@ public class GroupsApi {
@Transactional(Transactional.TxType.REQUIRED)
public Response updateGroup(
@PathParam("groupIdentifier") final String groupIdentifier,
- final JsonObject groupData
+ final GroupData groupData
) {
final Group group = findGroup(groupIdentifier);
boolean updated = false;
- if (!groupData.isNull("name")
- && !groupData.getString("name").matches("\\s*")
- && !groupData.getString("name").equals(group.getName())) {
- group.setName(groupData.getString("name"));
+ if (groupData.getName() != null
+ && !groupData.getName().matches("\\s*")
+ && !groupData.getName().equals(group.getName())) {
+ group.setName(groupData.getName());
updated = true;
}
@@ -210,14 +214,14 @@ public class GroupsApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonArray getMembers(
+ public List getMembers(
@PathParam("groupIdentifier") final String groupIdentifier
) {
return findGroup(groupIdentifier)
.getMemberships()
.stream()
- .map(GroupMembership::toJson)
- .collect(new JsonArrayCollector());
+ .map(GroupUserMembership::new)
+ .collect(Collectors.toList());
}
@PUT
@@ -277,15 +281,15 @@ public class GroupsApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonArray getRoleMemberships(
+ public List getRoleMemberships(
@PathParam("groupIdentifier")
final String groupIdentifier
) {
return findGroup(groupIdentifier)
.getRoleMemberships()
.stream()
- .map(RoleMembership::toJson)
- .collect(new JsonArrayCollector());
+ .map(PartyRoleMembership::new)
+ .collect(Collectors.toList());
}
@PUT
diff --git a/ccm-core/src/main/java/org/libreccm/security/RolesApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/RolesApi.java
similarity index 96%
rename from ccm-core/src/main/java/org/libreccm/security/RolesApi.java
rename to ccm-core/src/main/java/org/libreccm/api/admin/security/RolesApi.java
index 3b44125d7..273b78099 100644
--- a/ccm-core/src/main/java/org/libreccm/security/RolesApi.java
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/RolesApi.java
@@ -3,7 +3,7 @@
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
-package org.libreccm.security;
+package org.libreccm.api.admin.security;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository;
@@ -34,6 +34,14 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.Party;
+import org.libreccm.security.PartyRepository;
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.security.Role;
+import org.libreccm.security.RoleManager;
+import org.libreccm.security.RoleRepository;
+
/**
*
* @author Jens Pelzetter
diff --git a/ccm-core/src/main/java/org/libreccm/security/UsersApi.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/UsersApi.java
similarity index 85%
rename from ccm-core/src/main/java/org/libreccm/security/UsersApi.java
rename to ccm-core/src/main/java/org/libreccm/api/admin/security/UsersApi.java
index 546d05865..0fab94c27 100644
--- a/ccm-core/src/main/java/org/libreccm/security/UsersApi.java
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/UsersApi.java
@@ -16,22 +16,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
-package org.libreccm.security;
+package org.libreccm.api.admin.security;
+import org.libreccm.api.admin.security.dto.UserData;
+import org.libreccm.api.admin.security.dto.UserGroupMembership;
+import org.libreccm.api.admin.security.dto.PartyRoleMembership;
+import org.libreccm.api.dto.ListView;
import org.libreccm.core.CoreConstants;
import org.libreccm.core.api.ExtractedIdentifier;
import org.libreccm.core.api.IdentifierExtractor;
-import org.libreccm.core.api.JsonArrayCollector;
import java.net.URI;
import java.util.List;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
-import javax.json.Json;
-import javax.json.JsonArray;
-import javax.json.JsonObject;
-import javax.json.JsonObjectBuilder;
import javax.transaction.Transactional;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -47,6 +46,20 @@ import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.libreccm.security.AuthorizationRequired;
+import org.libreccm.security.Group;
+import org.libreccm.security.GroupManager;
+import org.libreccm.security.GroupRepository;
+import org.libreccm.security.RequiresPrivilege;
+import org.libreccm.security.Role;
+import org.libreccm.security.RoleManager;
+import org.libreccm.security.RoleRepository;
+import org.libreccm.security.User;
+import org.libreccm.security.UserManager;
+import org.libreccm.security.UserRepository;
+
+import java.util.stream.Collectors;
+
/**
* Provides RESTful API endpoints for managing users. Access to all endpoints
* defined by this class requires admin privileges.
@@ -84,7 +97,7 @@ public class UsersApi {
* @param limit How many users should be retrieved?
* @param offset The first user to retrieve
*
- * @return A JSON array with the all users.
+ * @return A list of {@link UserData} objects.
*/
@GET
@Path("/")
@@ -92,26 +105,19 @@ public class UsersApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonObject getUsers(
+ public ListView getUsers(
@QueryParam("limit") @DefaultValue("20") final int limit,
@QueryParam("offset") @DefaultValue("0") final int offset
) {
final long count = userRepository.countAll();
final List users = userRepository.findAll(limit, offset);
- return Json
- .createObjectBuilder()
- .add("count", count)
- .add("limit", limit)
- .add("offset", offset)
- .add(
- "users",
- users
- .stream()
- .map(User::toJson)
- .collect(new JsonArrayCollector())
- )
- .build();
+ return new ListView<>(
+ users.stream().map(UserData::new).collect(Collectors.toList()),
+ count,
+ limit,
+ offset
+ );
}
/**
@@ -119,7 +125,7 @@ public class UsersApi {
*
* @param identifierParam The identifier for the user.
*
- * @return A JSON representation of the user.
+ * @return A {@link UserData} object.
*/
@GET
@Path("/{userIdentifier}")
@@ -127,10 +133,10 @@ public class UsersApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonObject getUser(
+ public UserData getUser(
final @PathParam("userIdentifier") String identifierParam
) {
- return findUser(identifierParam).toJson();
+ return new UserData(findUser(identifierParam));
}
/**
@@ -152,46 +158,51 @@ public class UsersApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public Response addUser(final JsonObject userData) {
+ public Response addUser(final User userData) {
final String givenName;
- if (userData.isNull("givenName")) {
+ if (userData.getGivenName() == null) {
givenName = null;
} else {
- givenName = userData.getString("givenName");
+ givenName = userData.getGivenName();
}
final String familyName;
- if (userData.isNull("familyName")) {
+ if (userData.getFamilyName() == null) {
familyName = null;
} else {
- familyName = userData.getString("familyName");
+ familyName = userData.getFamilyName();
}
- if (userData.isNull("name")
- || userData.getString("name").matches("\\s*")) {
+ if (userData.getName() == null
+ || userData.getName().matches("\\s*")) {
return Response
.status(Response.Status.BAD_REQUEST)
.entity("Name for new user is missing.")
.build();
}
- final String name = userData.getString("name");
+ final String name = userData.getName();
- if (userData.isNull("emailAddress")
- || userData.getString("emailAddress").matches("\\s*")) {
+ if (userData.getPrimaryEmailAddress() == null
+ || userData.getPrimaryEmailAddress().getAddress() == null
+ || userData.getPrimaryEmailAddress().getAddress().matches(
+ "\\s*"
+ )) {
return Response
.status(Response.Status.BAD_REQUEST)
.entity("Name for new user is missing.")
.build();
}
- final String emailAddress = userData.getString("emailAddress");
+ final String emailAddress = userData
+ .getPrimaryEmailAddress()
+ .getAddress();
- if (userData.isNull("password")) {
+ if (userData.getPassword() == null) {
return Response
.status(Response.Status.BAD_REQUEST)
.entity("Password for new user is missing.")
.build();
}
- final String password = userData.getString("password");
+ final String password = userData.getPassword();
if (userRepository.findByName(name).isPresent()) {
return Response
@@ -247,30 +258,30 @@ public class UsersApi {
@Transactional(Transactional.TxType.REQUIRED)
public Response updateUser(
@PathParam("userIdentifier") final String userIdentifier,
- final JsonObject userData
+ final UserData userData
) {
final User user = findUser(userIdentifier);
boolean updated = false;
- if (!userData.isNull("familyName")
- && !userData.getString("familyName")
- .equals(user.getFamilyName())) {
- user.setFamilyName(userIdentifier);
+ if (userData.getFamilyName() != null
+ && !userData.getFamilyName().equals(user.getFamilyName())) {
+ user.setFamilyName(userData.getFamilyName());
updated = true;
}
- if (!userData.isNull("givenName")
- && !userData.getString("givenName").equals(user.getGivenName())) {
- user.setGivenName(userData.getString("givenName"));
+ if (userData.getGivenName() != null
+ && !userData.getGivenName().equals(user.getGivenName())) {
+ user.setGivenName(userData.getGivenName());
updated = true;
}
- if (!userData.isNull("emailAddress")
- && !userData.getString("emailAddress")
+ if (userData.getPrimaryEmailAddress() != null
+ && userData.getPrimaryEmailAddress().getAddress() != null
+ && !userData.getPrimaryEmailAddress().getAddress()
.equals(user.getPrimaryEmailAddress().getAddress())) {
user
.getPrimaryEmailAddress()
- .setAddress(userData.getString("emailAddress"));
+ .setAddress(userData.getPrimaryEmailAddress().getAddress());
updated = true;
}
@@ -317,14 +328,14 @@ public class UsersApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonArray getGroupMemberships(
+ public List getGroupMemberships(
@PathParam("userIdentifier") final String userIdentifier
) {
return findUser(userIdentifier)
.getGroupMemberships()
.stream()
- .map(GroupMembership::toJson)
- .collect(new JsonArrayCollector());
+ .map(UserGroupMembership::new)
+ .collect(Collectors.toList());
}
@PUT
@@ -385,15 +396,15 @@ public class UsersApi {
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
- public JsonArray getRoleMemberships(
+ public List getRoleMemberships(
@PathParam("userIdentifier")
final String userIdentifier
) {
return findUser(userIdentifier)
.getRoleMemberships()
.stream()
- .map(RoleMembership::toJson)
- .collect(new JsonArrayCollector());
+ .map(PartyRoleMembership::new)
+ .collect(Collectors.toList());
}
@PUT
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/EmailAddressData.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/EmailAddressData.java
new file mode 100644
index 000000000..bb54dd7fe
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/EmailAddressData.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.core.EmailAddress;
+
+import java.util.Objects;
+
+/**
+ * A data transfer object for serializing {@link EmailAddress} objects in the
+ * RESTFful API.
+ *
+ * @author Jens Pelzetter
+ */
+public class EmailAddressData {
+
+ private String address;
+
+ private boolean bouncing;
+
+ private boolean verified;
+
+ /**
+ * Creates a new empty {@code EmailAddressData} object.
+ */
+ public EmailAddressData() {
+ // Nothing
+ }
+
+ /**
+ * Creates a {@code EmailAddressData} object from the provided
+ * {@link EmailAddress} object.
+ *
+ * @param emailAddress
+ */
+ public EmailAddressData(final EmailAddress emailAddress) {
+ Objects.requireNonNull(
+ emailAddress,
+ "Can't create EmailAddressData object from null"
+ );
+ this.address = emailAddress.getAddress();
+ this.bouncing = emailAddress.isBouncing();
+ this.verified = emailAddress.isVerified();
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public boolean isBouncing() {
+ return bouncing;
+ }
+
+ public void setBouncing(boolean bouncing) {
+ this.bouncing = bouncing;
+ }
+
+ public boolean isVerified() {
+ return verified;
+ }
+
+ public void setVerified(boolean verified) {
+ this.verified = verified;
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupData.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupData.java
new file mode 100644
index 000000000..7a12d2355
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupData.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.Group;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class GroupData {
+
+ private long partyId;
+
+ private String uuid;
+
+ private String name;
+
+ private List memberships;
+
+ private List roleMemberships;
+
+ /**
+ * Parameterless constructor for generating empty instances.
+ */
+ public GroupData() {
+ memberships = new ArrayList<>();
+ roleMemberships = new ArrayList<>();
+ }
+
+ public GroupData(final Group group) {
+ partyId = group.getPartyId();
+ uuid = group.getUuid();
+ name = group.getName();
+ memberships = group
+ .getMemberships()
+ .stream()
+ .map(GroupUserMembership::new)
+ .collect(Collectors.toList());
+ roleMemberships = group
+ .getRoleMemberships()
+ .stream()
+ .map(PartyRoleMembership::new)
+ .collect(Collectors.toList());
+ }
+
+ public long getPartyId() {
+ return partyId;
+ }
+
+ public void setPartyId(final long partyId) {
+ this.partyId = partyId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public List getMemberships() {
+ return new ArrayList<>(memberships);
+ }
+
+ public void setMemberships(final List memberships) {
+ this.memberships = new ArrayList<>(memberships);
+ }
+
+ public List getRoleMemberships() {
+ return new ArrayList<>(roleMemberships);
+ }
+
+ public void setRoleMemberships(
+ final List roleMemberships
+ ) {
+ this.roleMemberships = new ArrayList<>(roleMemberships);
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupUserMembership.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupUserMembership.java
new file mode 100644
index 000000000..ea31bb61d
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/GroupUserMembership.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.GroupMembership;
+
+import java.util.Objects;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class GroupUserMembership {
+
+ private long membershipId;
+
+ private String uuid;
+
+ private PartyId user;
+
+ /**
+ * Parameterless constructor for creating empty instances.
+ */
+ public GroupUserMembership() {
+ // Nothing
+ }
+
+ public GroupUserMembership(final GroupMembership membership) {
+ Objects.requireNonNull(
+ "Can't create a GroupUserMembership from null."
+ );
+ membershipId = membership.getMembershipId();
+ uuid = membership.getUuid();
+ user = new PartyId(membership.getMember());
+ }
+
+ public long getMembershipId() {
+ return membershipId;
+ }
+
+ public void setMembershipId(final long membershipId) {
+ this.membershipId = membershipId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public PartyId getUser() {
+ return user;
+ }
+
+ public void setUser(final PartyId user) {
+ this.user = user;
+ }
+
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyId.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyId.java
new file mode 100644
index 000000000..c7566f4f1
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyId.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.Party;
+
+import java.util.Objects;
+
+/**
+ * A data transfer object providing the basic information for identifing
+ * a party (user or group).
+ *
+ * @author Jens Pelzetter
+ */
+public class PartyId {
+
+ private long partyId;
+
+ private String uuid;
+
+ private String name;
+
+ /**
+ * Parameterless constructor for generating an empty {@code GroupId} object.
+ */
+ public PartyId() {
+ // Nothing
+ }
+
+ /**
+ * Generate a {@code GroupId} object containing the data of the provided group.
+ * @param party
+ */
+ public PartyId(final Party party) {
+ Objects.requireNonNull(
+ party, "Can't create a PartyId object from null."
+ );
+ this.partyId = party.getPartyId();
+ this.uuid = party.getUuid();
+ this.name = party.getName();
+ }
+
+ public long getPartyId() {
+ return partyId;
+ }
+
+ public void setPartyId(final long partyId) {
+ this.partyId = partyId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyRoleMembership.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyRoleMembership.java
new file mode 100644
index 000000000..95ed334bd
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/PartyRoleMembership.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.RoleMembership;
+
+import java.util.Objects;
+
+/**
+ * Data Transfer Object containing the data about a role membership of a user.
+ *
+ * @author Jens Pelzetter
+ */
+public class PartyRoleMembership {
+
+ private long membershipId;
+
+ private String uuid;
+
+ private RoleId role;
+
+ /**
+ * Parameterless constructor for generating empty instances.
+ */
+ public PartyRoleMembership() {
+ // Nothing
+ }
+
+ /**
+ * Creates an instance from a {@link RoleMembership}.
+ * @param membership The {@link RoleMembership} from which the instance is created.
+ */
+ public PartyRoleMembership(final RoleMembership membership) {
+ Objects.requireNonNull(
+ membership,
+ "Can't create a UserRoleMembership from null."
+ );
+
+ membershipId = membership.getMembershipId();
+ uuid = membership.getUuid();
+ role = new RoleId(membership.getRole());
+ }
+
+ public long getMembershipId() {
+ return membershipId;
+ }
+
+ public void setMembershipId(final long membershipId) {
+ this.membershipId = membershipId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public RoleId getRole() {
+ return role;
+ }
+
+ public void setRole(final RoleId role) {
+ this.role = role;
+ }
+
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/RoleId.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/RoleId.java
new file mode 100644
index 000000000..bef1fdcdd
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/RoleId.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.Role;
+
+import java.util.Objects;
+
+/**
+ * Data Transfer Object containingthe data for identifing a {@link Role}
+ *
+ * @author Jens Pelzetter
+ */
+public class RoleId {
+
+ private long roleId;
+
+ private String uuid;
+
+ private String name;
+
+ /**
+ * Parameterless constructor for creating an empty instance.
+ */
+ public RoleId() {
+ // Nothing
+ }
+
+ public RoleId(final Role role) {
+ Objects.requireNonNull(role, "Can't create a RoleId object from null.");
+
+ roleId = role.getRoleId();
+ uuid = role.getUuid();
+ name = role.getName();
+ }
+
+ public long getRoleId() {
+ return roleId;
+ }
+
+ public void setRoleId(final long roleId) {
+ this.roleId = roleId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserData.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserData.java
new file mode 100644
index 000000000..175a6a490
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserData.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.User;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author Jens Pelzetter
+ */
+public class UserData {
+
+ private long partyId;
+
+ private String uuid;
+
+ private String name;
+
+ private String givenName;
+
+ private String familyName;
+
+ private EmailAddressData primaryEmailAddress;
+
+ private List emailAddresses;
+
+ private boolean banned;
+
+ private boolean passwordResetRequired;
+
+ private List groupMemberships;
+
+ private List roleMemberships;
+
+ /**
+ * Parameterless constructor for generating empty instances.
+ */
+ public UserData() {
+ emailAddresses = new ArrayList<>();
+ groupMemberships = new ArrayList<>();
+ roleMemberships = new ArrayList<>();
+ }
+
+ /**
+ * Creates an instance from a user.
+ *
+ * @param user The user from which the instance is generated.
+ */
+ public UserData(final User user) {
+ Objects.requireNonNull(
+ user,
+ "Can't generate a UserData object from null."
+ );
+ this.partyId = user.getPartyId();
+ this.uuid = user.getUuid();
+ this.name = user.getName();
+ this.givenName = user.getGivenName();
+ this.familyName = user.getFamilyName();
+ this.primaryEmailAddress = new EmailAddressData(
+ user.getPrimaryEmailAddress()
+ );
+ this.emailAddresses = user
+ .getEmailAddresses()
+ .stream()
+ .map(EmailAddressData::new)
+ .collect(Collectors.toList());
+ this.banned = user.isBanned();
+ this.passwordResetRequired = user.isPasswordResetRequired();
+ this.groupMemberships = user
+ .getGroupMemberships()
+ .stream()
+ .map(UserGroupMembership::new)
+ .collect(Collectors.toList());
+ this.roleMemberships = user
+ .getRoleMemberships()
+ .stream()
+ .map(PartyRoleMembership::new)
+ .collect(Collectors.toList());
+ }
+
+ public long getPartyId() {
+ return partyId;
+ }
+
+ public void setPartyId(final long partyId) {
+ this.partyId = partyId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(final String name) {
+ this.name = name;
+ }
+
+ public String getGivenName() {
+ return givenName;
+ }
+
+ public void setGivenName(final String givenName) {
+ this.givenName = givenName;
+ }
+
+ public String getFamilyName() {
+ return familyName;
+ }
+
+ public void setFamilyName(
+ final String familyName
+ ) {
+ this.familyName = familyName;
+ }
+
+ public EmailAddressData getPrimaryEmailAddress() {
+ return primaryEmailAddress;
+ }
+
+ public void setPrimaryEmailAddress(
+ final EmailAddressData primaryEmailAddress
+ ) {
+ this.primaryEmailAddress = primaryEmailAddress;
+ }
+
+ public List getEmailAddresses() {
+ return new ArrayList<>(emailAddresses);
+ }
+
+ public void setEmailAddresses(
+ final List emailAddresses
+ ) {
+ this.emailAddresses = new ArrayList<>(emailAddresses);
+ }
+
+ public boolean isBanned() {
+ return banned;
+ }
+
+ public void setBanned(boolean banned) {
+ this.banned = banned;
+ }
+
+ public boolean isPasswordResetRequired() {
+ return passwordResetRequired;
+ }
+
+ public void setPasswordResetRequired(
+ final boolean passwordResetRequired
+ ) {
+ this.passwordResetRequired = passwordResetRequired;
+ }
+
+ public List getGroupMemberships() {
+ return new ArrayList<>(groupMemberships);
+ }
+
+ public void setGroupMemberships(
+ final List groupMemberships
+ ) {
+ this.groupMemberships = new ArrayList<>(groupMemberships);
+ }
+
+ public List getRoleMemberships() {
+ return new ArrayList<>(roleMemberships);
+ }
+
+ public void setRoleMemberships(
+ final List roleMemberships
+ ) {
+ this.roleMemberships = new ArrayList<>(roleMemberships);
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserGroupMembership.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserGroupMembership.java
new file mode 100644
index 000000000..7657945ef
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/UserGroupMembership.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2020 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.api.admin.security.dto;
+
+import org.libreccm.security.GroupMembership;
+
+/**
+ * A data transfer object providing the data about a group membership of a user.
+ *
+ * @author Jens Pelzetter
+ */
+public class UserGroupMembership {
+
+ private long membershipId;
+
+ private String uuid;
+
+ private PartyId group;
+
+ /*
+ * Parameterless constructor for generating an empty instance of {@code
+ * UserGroupMembership}.
+ */
+ public UserGroupMembership() {
+ // Nothing
+ }
+
+ /**
+ * Creates a {@code UserGroupMembership} object from the provided
+ * {@link GroupMembership} entity.
+ *
+ * @param membership The entity from which the instance is generated.
+ */
+ public UserGroupMembership(final GroupMembership membership) {
+ this.membershipId = membership.getMembershipId();
+ this.uuid = membership.getUuid();
+ this.group = new PartyId(membership.getGroup());
+ }
+
+ public long getMembershipId() {
+ return membershipId;
+ }
+
+ public void setMembershipId(final long membershipId) {
+ this.membershipId = membershipId;
+ }
+
+ public String getUuid() {
+ return uuid;
+ }
+
+ public void setUuid(final String uuid) {
+ this.uuid = uuid;
+ }
+
+ public PartyId getGroup() {
+ return group;
+ }
+
+ public void setGroup(final PartyId group) {
+ this.group = group;
+ }
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/package-info.java b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/package-info.java
new file mode 100644
index 000000000..4faf8ccd3
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/admin/security/dto/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 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
+ */
+/**
+ * Data Transfer Objects for the Security Admin APIs.
+ */
+package org.libreccm.api.admin.security.dto;
diff --git a/ccm-core/src/main/java/org/libreccm/api/dto/ListView.java b/ccm-core/src/main/java/org/libreccm/api/dto/ListView.java
new file mode 100644
index 000000000..c80b7c121
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/dto/ListView.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.api.dto;
+
+import java.util.List;
+
+/**
+ * Data Transfer Object for a list of objects.
+ *
+ * @author Jens Pelzetter
+ * @param The type of object in the list.
+ */
+public class ListView {
+
+ /**
+ * The list itself.
+ */
+ private final List list;
+
+ /**
+ * The number of objects existing in the database.
+ */
+ private final long count;
+
+ /**
+ * The maximum number of objects returned for one request.
+ */
+ private final long limit;
+
+ /**
+ * The first object of all objects found in the {@link #list}.
+ */
+ private final long offset;
+
+ public ListView(
+ final List list,
+ final long count,
+ final long limit,
+ final long offset
+ ) {
+ this.list = list;
+ this.count = count;
+ this.limit = limit;
+ this.offset = offset;
+ }
+
+ public List getList() {
+ return list;
+ }
+
+ public long getCount() {
+ return count;
+ }
+
+ public long getLimit() {
+ return limit;
+ }
+
+ public long getOffset() {
+ return offset;
+ }
+
+
+
+}
diff --git a/ccm-core/src/main/java/org/libreccm/api/dto/package-info.java b/ccm-core/src/main/java/org/libreccm/api/dto/package-info.java
new file mode 100644
index 000000000..651b5cebb
--- /dev/null
+++ b/ccm-core/src/main/java/org/libreccm/api/dto/package-info.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 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
+ */
+/**
+ * Common Data Transfer Objects for the RESTful API.
+ */
+package org.libreccm.api.dto;
diff --git a/ccm-core/src/main/java/org/libreccm/security/Party.java b/ccm-core/src/main/java/org/libreccm/security/Party.java
index 0690f6fc2..db7a0e529 100644
--- a/ccm-core/src/main/java/org/libreccm/security/Party.java
+++ b/ccm-core/src/main/java/org/libreccm/security/Party.java
@@ -37,7 +37,6 @@ import java.util.Objects;
import java.util.Set;
import javax.json.Json;
-import javax.json.JsonArray;
import javax.json.JsonObject;
import javax.json.JsonObjectBuilder;
import javax.persistence.Column;