package controllers;
import static play.data.Form.form;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import models.Organisation;
import models.Role;
import models.User;
import org.apache.commons.lang3.StringUtils;
import play.Logger;
import play.data.DynamicForm;
import play.data.Form;
import play.data.validation.ValidationError;
import play.libs.Json;
import play.mvc.BodyParser;
import play.mvc.Result;
import play.mvc.Security;
import uk.bl.Const;
import uk.bl.api.PasswordHash;
import views.html.users.edit;
import views.html.users.newForm;
import views.html.users.list;
import views.html.users.view;
import com.fasterxml.jackson.databind.JsonNode;
/**
* Manage curators.
*/
@Security.Authenticated(SecuredController.class)
public class UserController extends AbstractController {
/**
* Display the Curators.
*/
public static Result index() {
Logger.debug("Curators.index()");
return GO_HOME;
}
public static Result GO_HOME = redirect(
routes.UserController.list(0, "name", "asc", "")
);
/**
* Display the paginated list of Curators.
*
* @param page Current page number (starts from 0)
* @param sortBy Column to be sorted
* @param order Sort order (either asc or desc)
* @param filter Filter applied on target urls
*/
public static Result list(int pageNo, String sortBy, String order, String filter) {
Logger.debug("Curators.list() " + filter);
return ok(
list.render(
"Curators",
User.findByEmail(request().username()),
filter,
User.page(pageNo, 10, sortBy, order, filter),
sortBy,
order)
);
}
/**
* Searching
*/
public static Result search() {
DynamicForm form = form().bindFromRequest();
String action = form.get("action");
String query = form.get(Const.NAME);
Logger.debug("query: " + query);
Logger.debug("action: " + action);
if (StringUtils.isBlank(query)) {
Logger.debug("Curator's name is empty. Please write name in search window.");
flash("message", "Please enter a name in the search window");
return redirect(
routes.UserController.list(0, "name", "asc", "")
);
}
int pageNo = getQueryParamAsInt(Const.PAGE_NO, 0);
String sort = getQueryParam(Const.SORT_BY);
String order = getQueryParam(Const.ORDER);
if (StringUtils.isEmpty(action)) {
return badRequest("You must provide a valid action");
} else {
if (action.equals("add")) {
return redirect(
routes.UserController.newForm(query)
);
} else if (action.equals("search")) {
return redirect(routes.UserController.list(pageNo, sort, order, query));
} else {
return badRequest("This action is not allowed");
}
}
}
@BodyParser.Of(BodyParser.Json.class)
public static Result filterByJson(String name) {
JsonNode jsonData = null;
if (name != null) {
List<User> users = User.filterByName(name);
jsonData = Json.toJson(users);
}
return ok(jsonData);
}
public static Result view(Long id) {
User curator = User.findById(id);
if (curator == null) return notFound("There is no Curator with ID " + id);
User user = User.findByEmail(request().username());
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
}
List<Organisation> organisations = Organisation.findAll();
return ok(view.render(curator, user, roles, organisations));
}
public static Result viewAct(String url) {
User curator = User.findByUrl(url);
User user = User.findByEmail(request().username());
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
} List<Organisation> organisations = Organisation.findAll();
return ok(view.render(curator, user, roles, organisations));
}
public static Result viewWct(String url) {
User curator = User.findByWct(url);
User user = User.findByEmail(request().username());
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
} List<Organisation> organisations = Organisation.findAll();
return ok(view.render(curator, user, roles, organisations));
}
public static Result newForm(String name) {
User user = User.findByEmail(request().username());
Form<User> userForm = Form.form(User.class);
User curator = new User();
if (StringUtils.isNotBlank(name)) {
curator.name = name;
}
userForm = userForm.fill(curator);
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
}
Map<String,String> organisations = Organisation.options();
return ok(newForm.render(userForm, user, roles, organisations));
}
public static Result edit(Long id) {
User curator = User.findById(id);
if (curator == null) return notFound("There is no Curator with ID " + id);
User user = User.findByEmail(request().username());
Form<User> userForm = Form.form(User.class);
userForm = userForm.fill(curator);
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
}
List<Role> curatorRoles = curator.roles;
Map<String,String> organisations = Organisation.options();
Logger.debug("roles: " + curator.roles.size());
String currentEmail = curator.email;
return ok(edit.render(userForm, user, id, roles, organisations, curatorRoles, currentEmail));
}
public static Result info(Form<User> form, Long id, String currentEmail) {
User user = User.findByEmail(request().username());
User curator = User.findById(id);
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
}
List<Role> curatorRoles = curator.roles;
Map<String,String> organisations = Organisation.options();
return badRequest(edit.render(form, user, id, roles, organisations, curatorRoles, currentEmail));
}
public static Result newInfo(Form<User> form) {
User user = User.findByEmail(request().username());
List<Role> roles = null;
if (user.isSysAdmin()) {
roles = Role.findAll();
} else {
roles = Role.findNonSysAdminRoles();
}
Map<String,String> organisations = Organisation.options();
return badRequest(newForm.render(form, user, roles, organisations));
}
public static Result save() {
DynamicForm requestData = form().bindFromRequest();
String action = requestData.get("action");
Logger.debug("action: " + action);
if (StringUtils.isNotEmpty(action)) {
if (action.equals("save")) {
Form<User> filledForm = form(User.class).bindFromRequest();
if(filledForm.hasErrors()) {
Logger.debug("errors: " + filledForm.errors());
return newInfo(filledForm);
}
String email = filledForm.get().email;
if (StringUtils.isNotBlank(email)) {
User user = User.findByEmail(email.toLowerCase().trim());
if (user != null) {
ValidationError ve = new ValidationError("email", "There is already a user account with that email address. Please check and enter a different email address.");
filledForm.reject(ve);
return newInfo(filledForm);
}
}
Map<String, String[]> formParams = request().body().asFormUrlEncoded();
List<Role> newRoles = new ArrayList<Role>();
String[] roleValues = formParams.get("rolesList");
if (roleValues != null) {
for(String roleValue: roleValues) {
Long roleId = Long.valueOf(roleValue);
Role tag = Role.findById(roleId);
newRoles.add(tag);
}
filledForm.get().roles = newRoles;
}
filledForm.get().email = email.toLowerCase().trim();
String password = requestData.get("password");
if (StringUtils.isEmpty(password)) {
Logger.debug("The password field is empty.");
// flash("message", "The password field is empty.");
ValidationError ve = new ValidationError("password", "The password field is empty.");
filledForm.reject(ve);
return newInfo(filledForm);
}
try {
filledForm.get().password = PasswordHash.createHash(password);
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
Logger.error("change password - no algorithm error: " + e);
ValidationError ve = new ValidationError("password", e.getMessage());
filledForm.reject(ve);
return newInfo(filledForm);
}
filledForm.get().save();
flash("message", "Curator " + filledForm.get().name + " has been created");
return redirect(routes.UserController.view(filledForm.get().id));
}
}
return null;
}
public static Result update(Long id) {
DynamicForm requestData = form().bindFromRequest();
Form<User> filledForm = form(User.class).bindFromRequest();
Logger.debug("hasGlobalErrors: " + filledForm.hasGlobalErrors());
Logger.debug("hasErrors: " + filledForm.hasErrors());
String action = requestData.get("action");
String currentEmail = requestData.get("currentEmail");
Logger.debug("action: " + action);
if (StringUtils.isNotEmpty(action)) {
if (action.equals("save")) {
if (filledForm.hasErrors()) {
Logger.debug("hasErrors: " + filledForm.errors());
return info(filledForm, id, currentEmail);
}
String oldPassword = requestData.get("oldpassword");
String newPassword = requestData.get("newpassword");
if (StringUtils.isEmpty(newPassword) != StringUtils.isEmpty(oldPassword)) {
Logger.debug("To change password, both password fields need to be filled in.");
// flash("message", "The password field is empty.");
ValidationError e = new ValidationError("password", "To change password, both password fields need to be filled in.");
filledForm.reject(e);
return info(filledForm, id, currentEmail);
}
/**
* Change password only if both filled in
*/
if (StringUtils.isNotBlank(newPassword) && StringUtils.isNotBlank(oldPassword)) {
try {
User dbUser = User.findById(id);
String userDbPassword = dbUser.password;
boolean isValidOldPassword = PasswordHash.validatePassword(oldPassword, userDbPassword);
if (!isValidOldPassword) {
Logger.debug("The old password is not correct.");
flash("message", "The old password is not correct.");
return info(filledForm, id, currentEmail);
} else {
filledForm.get().password = PasswordHash.createHash(newPassword);
}
} catch (NoSuchAlgorithmException e) {
Logger.debug("change password - no algorithm error: " + e);
} catch (InvalidKeySpecException e) {
Logger.debug("change password - key specification error: " + e);
}
}
// need to check the previous password
String email = filledForm.get().email;
Logger.debug("email: " + currentEmail + ", " + email);
if (!currentEmail.equalsIgnoreCase(email)) {
User user = User.findByEmail(email.trim());
if (user != null) {
ValidationError ve = new ValidationError("email", "There is already a user account with that email address. Please check and enter a different email address.");
filledForm.reject(ve);
return info(filledForm, id, currentEmail);
}
}
Map<String, String[]> formParams = request().body().asFormUrlEncoded();
List<Role> newRoles = new ArrayList<Role>();
String[] roleValues = formParams.get("rolesList");
if (roleValues != null) {
for(String roleValue: roleValues) {
Long roleId = Long.valueOf(roleValue);
Role tag = Role.findById(roleId);
newRoles.add(tag);
}
filledForm.get().roles = newRoles;
}
// if (getFormParam(Const.EMAIL).length() > 0
// && User.findByEmail(getFormParam(Const.EMAIL)) != null
// && !getFormParam(Const.EMAIL).equals(user.email)) {
// String msg = "The given email '" + getFormParam(Const.EMAIL) +
// "' already exists in database. Please give another email or use existing user.";
// Logger.debug(msg);
// flash("message", msg);
// if (getFormParam(Const.PASSWORD) == null || getFormParam(Const.PASSWORD).length() == 0) {
// Logger.debug("The password field is empty.");
// flash("message", "The password field is empty.");
// return info();
// } else {
// user.password = getFormParam(Const.PASSWORD);
// try {
// user.password = PasswordHash.createHash(user.password);
// } catch (NoSuchAlgorithmException e) {
// Logger.debug("change password - no algorithm error: " + e);
// } catch (InvalidKeySpecException e) {
// Logger.debug("change password - key specification error: " + e);
// }
filledForm.get().email = email.toLowerCase();
filledForm.get().update(id);
flash("message", "Curator " + filledForm.get().name + " has been updated");
return redirect(routes.UserController.view(filledForm.get().id));
} else if (action.equals("delete")) {
User curator = User.findById(id);
flash("message", "Curator " + filledForm.get().name + " has been deleted");
curator.delete();
return redirect(routes.UserController.index());
}
}
return null;
}
public static Result adminPasswordReset() {
return null;
}
public static Result sites(Long id) {
// user.targets?? or have to get again for paging
return redirect(routes.TargetController.userTargets(0, "title", "asc", "", id, 0L, 0L));
}
// public static Result resetPassword(String email) {
//
// return redirect(routes.UserController.resetPassword(String email, String password);
// }
// public static Result save() {
// Result res = null;
//
//// user.name = getFormParam(Const.NAME);
//// if (getFormParam(Const.EMAIL) != null) {
//// try {
//
//// return info();
//// }
//// } catch (Exception e) {
//// Logger.debug("Given email is not yet in database");
//// }
//// user.email = getFormParam(Const.EMAIL);
//// }
//// if (getFormParam(Const.ORGANISATION) != null) {
//// if (!getFormParam(Const.ORGANISATION).toLowerCase().contains(Const.NONE)) {
////// Logger.debug("organisation: " + getFormParam(Const.ORGANISATION));
//// user.affiliation = Organisation.findByTitle(getFormParam(Const.ORGANISATION)).url;
//// user.updateOrganisation();
//// } else {
//// user.affiliation = Const.NONE;
//// }
//// }
//// String roleStr = "";
//// List<Role> roleList = Role.findAll();
//// Iterator<Role> roleItr = roleList.iterator();
//// while (roleItr.hasNext()) {
//// Role role = roleItr.next();
//// if (getFormParam(role.name) != null) {
//// boolean roleFlag = Utils.getNormalizeBooleanString(getFormParam(role.name));
//// if (roleFlag) {
//// if (roleStr.length() == 0) {
//// roleStr = role.name;
//// } else {
//// roleStr = roleStr + ", " + role.name;
//// }
//// }
//// }
//// }
//// Utils.removeAssociationFromDb(Const.ROLE_USER, Const.ID + "_" + Const.USER, user.id);
//// if (roleStr.length() == 0) {
//// user.roles = null;
//// } else {
//// user.roles = Role.convertUrlsToObjects(roleStr);
//// }
////// Logger.debug("roleStr: "+ roleStr + ", user.role_to_user size: " + user.role_to_user.size());
//// if (getFormParam(Const.REVISION) != null) {
//// user.revision = getFormParam(Const.REVISION);
//// }
//// } catch (Exception e) {
//// Logger.debug("User not existing exception");
//// }
////
//// if (!isExisting) {
//
//// }
//// Ebean.save(user);
//// Logger.debug("save user: " + user.toString());
//// } else {
//// if (!(getFormParam(Const.PASSWORD) == null || getFormParam(Const.PASSWORD).length() == 0
//// || getFormParam(Const.OLD_PASSWORD) == null || getFormParam(Const.OLD_PASSWORD).length() == 0)) {
//// String oldInputPassword = getFormParam(Const.OLD_PASSWORD);
//// user.password = getFormParam(Const.PASSWORD);
//// try {
//// String userDbPassword = User.findByUid(user.id).password;
//// boolean isValidOldPassword = PasswordHash.validatePassword(oldInputPassword, userDbPassword);
//// if (!isValidOldPassword) {
//// Logger.debug("The old password is not correct.");
//// flash("message", "The old password is not correct.");
//// return info();
//// } else {
//// user.password = PasswordHash.createHash(user.password);
//// }
//// } catch (NoSuchAlgorithmException e) {
//// Logger.debug("change password - no algorithm error: " + e);
//// } catch (InvalidKeySpecException e) {
//// Logger.debug("change password - key specification error: " + e);
//// }
//// }
//// Logger.debug("update user: " + user.toString());
//// Ebean.update(user);
//// }
//// res = redirect(routes.Curators.edit(user.id));
//// }
//// if (delete != null) {
//// User user = User.findByUrl(getFormParam(Const.URL));
//// Ebean.delete(user);
//// res = redirect(routes.Curators.index());
//// }
// return res;
// }
/**
* This method checks if this User has a role passed by its id.
* @param userId
* @return true if exists
*/
public static String showRoles(Long userId) {
String res = "";
User user = User.findById(userId);
if (user.roles != null && user.roles.size() > 0) {
Iterator<Role> itr = user.roles.iterator();
while (itr.hasNext()) {
Role role = itr.next();
if (res.length() == 0) {
res = role.name;
} else {
res = res + Const.COMMA + " " + role.name;
}
}
}
return res;
}
}