diff --git a/ccm-core/src/main/java/org/libreccm/core/api/CcmCoreApi.java b/ccm-core/src/main/java/org/libreccm/core/api/CcmCoreApi.java index 4c4802bb7..e75fc3b26 100644 --- a/ccm-core/src/main/java/org/libreccm/core/api/CcmCoreApi.java +++ b/ccm-core/src/main/java/org/libreccm/core/api/CcmCoreApi.java @@ -20,7 +20,7 @@ import javax.ws.rs.core.Application; * * @author Jens Pelzetter */ -@ApplicationPath("/api/ccm-core") +@ApplicationPath("/api") public class CcmCoreApi extends Application { @Override 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 0cad09b9c..0690f6fc2 100644 --- a/ccm-core/src/main/java/org/libreccm/security/Party.java +++ b/ccm-core/src/main/java/org/libreccm/security/Party.java @@ -38,6 +38,7 @@ import java.util.Set; import javax.json.Json; import javax.json.JsonArray; +import javax.json.JsonObject; import javax.json.JsonObjectBuilder; import javax.persistence.Column; import javax.persistence.Entity; @@ -204,14 +205,12 @@ public class Party implements Serializable { public boolean canEqual(final Object obj) { return obj instanceof Party; } + + public JsonObject toJson() { + return buildJson().build(); + } public JsonObjectBuilder buildJson() { - final JsonArray array = roleMemberships - .stream() - .map(RoleMembership::buildJson) - .map(JsonObjectBuilder::build) - .collect(new JsonArrayCollector()); - return Json .createObjectBuilder() .add("partyId", partyId) diff --git a/ccm-core/src/main/java/org/libreccm/security/User.java b/ccm-core/src/main/java/org/libreccm/security/User.java index ce71aa92c..a124e2742 100644 --- a/ccm-core/src/main/java/org/libreccm/security/User.java +++ b/ccm-core/src/main/java/org/libreccm/security/User.java @@ -360,7 +360,7 @@ public class User extends Party implements Serializable, Exportable { public boolean canEqual(final Object obj) { return obj instanceof User; } - + @Override public JsonObjectBuilder buildJson() { final JsonArrayBuilder emailAddressesArrayBuilder = Json.createArrayBuilder(); diff --git a/ccm-core/src/main/java/org/libreccm/security/UsersApi.java b/ccm-core/src/main/java/org/libreccm/security/UsersApi.java index b14e840a0..77f1119da 100644 --- a/ccm-core/src/main/java/org/libreccm/security/UsersApi.java +++ b/ccm-core/src/main/java/org/libreccm/security/UsersApi.java @@ -18,21 +18,25 @@ */ package org.libreccm.security; -import org.apache.shiro.authz.annotation.RequiresAuthentication; import org.libreccm.core.CoreConstants; -import org.libreccm.core.api.ApiConstants; import org.libreccm.core.api.ExtractedIdentifier; import org.libreccm.core.api.IdentifierExtractor; import org.libreccm.core.api.JsonArrayCollector; +import java.net.URI; + import javax.enterprise.context.RequestScoped; import javax.inject.Inject; 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; import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; @@ -55,6 +59,9 @@ public class UsersApi { @Inject private UserRepository userRepository; + @Inject + private UserManager userManager; + @GET @Path("/") @Produces(MediaType.APPLICATION_JSON) @@ -82,6 +89,237 @@ public class UsersApi { public JsonObject getUser( final @PathParam("userIdentifier") String identifierParam ) { + return findUser(identifierParam).toJson(); + } + + @POST + @Path("/") + @Consumes(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response addUser(final JsonObject userData) { + + final String givenName; + if (userData.isNull("givenName")) { + givenName = null; + } else { + givenName = userData.getString("givenName"); + } + + final String familyName; + if (userData.isNull("familyName")) { + familyName = null; + } else { + familyName = userData.getString("familyName"); + } + + if (userData.isNull("name") + || userData.getString("name").matches("\\s*")) { + return Response + .status(Response.Status.BAD_REQUEST) + .entity("Name for new user is missing.") + .build(); + } + final String name = userData.getString("name"); + + if (userData.isNull("emailAddress") + || userData.getString("emailAddress").matches("\\s*")) { + return Response + .status(Response.Status.BAD_REQUEST) + .entity("Name for new user is missing.") + .build(); + } + final String emailAddress = userData.getString("emailAddress"); + + if (userData.isNull("password")) { + return Response + .status(Response.Status.BAD_REQUEST) + .entity("Password for new user is missing.") + .build(); + } + final String password = userData.getString("password"); + + if (userRepository.findByName(name).isPresent()) { + return Response + .status(Response.Status.CONFLICT) + .entity( + String.format( + "A user with the name %s already exists.", name + ) + ) + .build(); + } + + if (userRepository.findByEmailAddress(emailAddress).isPresent()) { + return Response + .status(Response.Status.CONFLICT) + .entity( + String.format( + "A user with the email address %s already exists", + emailAddress + ) + ) + .build(); + } + + final User user = userManager.createUser( + givenName, familyName, name, emailAddress, password + ); + + return Response + .status(Response.Status.CREATED) + .contentLocation( + URI.create(String.format("/api/users/%s", user.getName()) + ) + ) + .build(); + } + + @PUT + @Path("/{userIdentifier}") + @Consumes(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response updateUser( + @PathParam("userIdentifier") + final String userIdentifier, + final JsonObject userData + ) { + final User user = findUser(userIdentifier); + + boolean updated = false; + if (!userData.isNull("familyName") + && !userData.getString("familyName").equals(user.getFamilyName())) { + user.setFamilyName(userIdentifier); + updated = true; + } + + if (!userData.isNull("givenName") + && !userData.getString("givenName").equals(user.getGivenName())) { + user.setGivenName(userData.getString("givenName")); + updated = true; + } + + if (!userData.isNull("emailAddress") + && !userData.getString("emailAddress") + .equals(user.getPrimaryEmailAddress().getAddress()) + ) { + user + .getPrimaryEmailAddress() + .setAddress(userData.getString("emailAddress")); + updated = true; + } + + if (updated) { + userRepository.save(user); + } + + return Response + .status(Response.Status.OK) + .entity( + String.format("User %s updated successfully.", user.getName()) + ) + .build(); + } + + @DELETE + @Path("/{userIdentifier}") + @Consumes(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response deleteUser( + @PathParam("userIdentifier") + final String userIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @GET + @Path("/{userIdentifier}/groups") + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public JsonArray getGroupMemberships( + @PathParam("userIdentifier") + final String userIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @PUT + @Path("/{userIdentifier}/groups/{groupIdentifier}") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response addGroupMembership( + @PathParam("userIdentifier") + final String userIdentifier, + @PathParam("groupIdentifier") + final String groupIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @DELETE + @Path("/{userIdentifier}/groups/{groupIdentifier}") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response removeGroupMembership( + @PathParam("userIdentifier") + final String userIdentifier, + @PathParam("groupIdentifier") + final String groupIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @GET + @Path("/{userIdentifier}/roles") + @Produces(MediaType.APPLICATION_JSON) + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public JsonArray getRoleMemberships( + @PathParam("userIdentifier") + final String userIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @PUT + @Path("/{userIdentifier}/groups/{roleIdentifier}") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response addRoleMembership( + @PathParam("userIdentifier") + final String userIdentifier, + @PathParam("roleIdentifier") + final String roleIdentifier + ) { + throw new UnsupportedOperationException(); + } + + @DELETE + @Path("/{userIdentifier}/groups/{roleIdentifier}") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public Response removeRoleMembership( + @PathParam("userIdentifier") + final String userIdentifier, + @PathParam("roleIdentifier") + final String roleIdentifier + ) { + throw new UnsupportedOperationException(); + } + + private User findUser(final String identifierParam) { final ExtractedIdentifier identifier = identifierExtractor .extractIdentifier(identifierParam); @@ -96,9 +334,7 @@ public class UsersApi { identifier.getIdentifier() ), Response.Status.NOT_FOUND) - ) - .buildJson() - .build(); + ); case UUID: return userRepository .findByUuid(identifier.getIdentifier()) @@ -109,9 +345,7 @@ public class UsersApi { identifier.getIdentifier() ), Response.Status.NOT_FOUND) - ) - .buildJson() - .build(); + ); default: return userRepository .findByName(identifier.getIdentifier()) @@ -122,9 +356,7 @@ public class UsersApi { identifier.getIdentifier() ), Response.Status.NOT_FOUND) - ) - .buildJson() - .build(); + ); } }