package controllers; import java.util.ArrayList; import java.util.List; import models.User; import models.helpers.UserConnectionHelper; import notifiers.Mails; import org.apache.commons.lang.StringUtils; import play.Logger; import play.data.validation.Error; import DTO.UserDTO; import DTO.UserSummaryDTO; import assemblers.UserAssembler; import assemblers.UserSummaryAssembler; import com.google.gson.JsonObject; /** * * @author Alex Jarvis axj7@aber.ac.uk */ public class Users extends ServiceApplicationController { /** * Returns all users that the current authorised user is connected to * (not all users in the system). */ public static void index() { User authUser = getAuthorisedUser(); renderJSON(UserSummaryAssembler.writeDTOs(authUser)); } /** * Creates a new user in the system. * * @param body */ public static void create(JsonObject body) { if (body != null && body.isJsonObject()) { UserDTO userDTO = UserAssembler.userDTOWithJsonObject(body); validation.valid(userDTO); if (validation.hasErrors()) { for (Error error : validation.errors()) { Logger.debug(error.getKey() + " : " + error.message()); } error(400, "Validation Errors"); } if (userDTO != null) { // Check for existing users User checkEmail = User.find("byEmail", userDTO.email).first(); if (checkEmail != null) { error(400, "Email already exists"); } // Check for existing phone number if (StringUtils.isNotBlank(userDTO.mobileNumber)) { User checkNumber = User.find("byMobileNumber", userDTO.mobileNumber).first(); if (checkNumber != null) { error(400, "Mobile number already exists"); } } // Create user UserDTO newUserDTO = UserAssembler.createUser(userDTO); // Send email Mails.welcome(newUserDTO); response.status = 201; renderJSON(newUserDTO); } } else { badRequest(); } } /** * Shows information on a user in the system. * * Special behaviour is applied if the user is the authorised user * and only users that the authorised user is connected to are allowed * to be shown. * * @param id */ public static void show(String id) { User authUser = getAuthorisedUser(); if (id.equals(authUser.id.toString()) || id.equals(authUser.email)) { renderJSON(UserAssembler.writeDTO(authUser, true)); } else { User user = getUserFromIdOrEmail(id); // is the user connected? if (user != null) { if (UserConnectionHelper.isUsersConnected(authUser, user)) { renderJSON(UserAssembler.writeDTO(user, false)); } else { error(400, "User not connected"); } } else { notFound(); } } } /** * Updates the User specified in the resource URI with the contents of the UserDTO * in the body of the request. * * @param user */ public static void update(String id, JsonObject body) { // Only able to update the authorised user User authUser = getAuthorisedUser(); User user = getUserFromIdOrEmail(id); if (user != null && user.equals(authUser)) { if (body != null && body.isJsonObject()) { UserDTO userDTO = UserAssembler.userDTOWithJsonObject(body); if (userDTO != null) { // Validation validation.valid(userDTO); if (validation.hasErrors()) { for (Error error : validation.errors()) { Logger.debug(error.getKey() + " : " + error.message()); } error(400, "Validation Errors"); } // If the email has changed check that another user does not have it. if (!authUser.email.equalsIgnoreCase(userDTO.email)) { User checkUser = User.find("byEmail", userDTO.email).first(); if (checkUser != null) { error(400, "Email already exists"); } } // Update user userDTO.id = user.id; renderJSON(UserAssembler.updateUser(userDTO)); } } } badRequest(); } /** * Deletes the connection between the authorised User and the User specified. * @param id */ public static void delete(String id) { User authUser = getAuthorisedUser(); User otherUser = getNonAuthorisedUser(id); if (otherUser != null) { if (UserConnectionHelper.removeUserConnection(authUser, otherUser)) { ok(); } else { badRequest(); } } notFound(); } /** * * @param id */ public static void addUserRequest(String id) { User authUser = getAuthorisedUser(); User otherUser = getNonAuthorisedUser(id); if (otherUser != null) { if (UserConnectionHelper.createUserConnectionRequest(authUser, otherUser)) { // Send email Mails.newFriendRequest(UserAssembler.writeDTO(otherUser), UserAssembler.writeDTO(authUser)); ok(); } } badRequest(); } /** * * @param id */ public static void acceptUserRequest(String id) { User authUser = getAuthorisedUser(); User otherUser = getNonAuthorisedUser(id); if (otherUser != null) { if (UserConnectionHelper.removeUserConnectionRequest(otherUser, authUser)) { UserConnectionHelper.createUserConnection(authUser, otherUser); ok(); } } badRequest(); } /** * * @param id */ public static void declineUserRequest(String id) { User authUser = getAuthorisedUser(); User otherUser = getNonAuthorisedUser(id); if (otherUser != null) { if (UserConnectionHelper.removeUserConnectionRequest(otherUser, authUser)) { ok(); } } badRequest(); } /** * Searches for users * @param query */ public static void searchUsers(String query) { query = query.trim(); String firstName = query; String lastName = query; String[] names = query.split("\\s"); if (names.length >= 2) { firstName = names[0]; lastName = names[1]; } // TODO: move this query away from the controller and/or implement lucene based search List<User> userResults = User.find("select u from User u " + "where LOWER(u.firstName) like LOWER(?) " + "or LOWER(u.lastName) like LOWER(?)", firstName+"%", lastName+"%").fetch(50); if (userResults != null && userResults.size() > 0) { List<UserSummaryDTO> userSummaryList = new ArrayList<UserSummaryDTO>(); for (User user : userResults) { userSummaryList.add(UserSummaryAssembler.writeRestrictedDTO(user)); } renderJSON(userSummaryList); } else { error(404, "Not found"); } } /** * Returns the User where the User cannot be the authorised User. * * When the id matches the authorised User, this method returns null. * * @param id * @return */ private static User getNonAuthorisedUser(String id) { User authUser = getAuthorisedUser(); // If the id is the authorised user if (!id.equals(authUser.id.toString()) && !id.equals(authUser.email)) { return getUserFromIdOrEmail(id); } return null; } /** * Returns the User from the id parameter in the URL. This could either be the * id of type Long held against the User - or it could be their email. * * @param id * @return */ private static User getUserFromIdOrEmail(String id) { // determine the ID type boolean emailID = true; Long longID = null; try { longID = new Long(id); emailID = false; } catch (NumberFormatException e) { Logger.debug("User id is not a number, maybe an email"); } // get the User User user = null; if (emailID) { user = User.find("byEmail", id).first(); } else { user = User.findById(longID); } if (user != null) { return user; } return null; } }