REST API for managing users

Jens Pelzetter 2020-05-25 19:59:04 +02:00
parent 0a03224761
commit ce2147315d
4 changed files with 250 additions and 19 deletions

View File

@ -20,7 +20,7 @@ import javax.ws.rs.core.Application;
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@ApplicationPath("/api/ccm-core")
@ApplicationPath("/api")
public class CcmCoreApi extends Application {
@Override

View File

@ -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)

View File

@ -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();

View File

@ -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();
);
}
}