Skip to content

Commit

Permalink
Merge pull request #941 from Creaticide/feature/OS-376
Browse files Browse the repository at this point in the history
User pagination/search + password validation
  • Loading branch information
ZakarFin authored Mar 30, 2023
2 parents 9365ab4 + d784d3d commit ea0b5d3
Show file tree
Hide file tree
Showing 13 changed files with 226 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.json.JSONException;
import org.json.JSONObject;
import org.oskari.log.AuditLog;
import org.oskari.user.util.UserHelper;

import java.util.List;

Expand All @@ -29,6 +30,9 @@ public class UsersHandler extends RestActionHandler {
private static final String PARAM_SCREENNAME = "user";
private static final String PARAM_PASSWORD = "pass";
private static final String PARAM_EMAIL = "email";
private static final String PARAM_LIMIT = "limit";
private static final String PARAM_OFFSET = "offset";
private static final String PARAM_SEARCH = "search";

@Override
public void init() {
Expand All @@ -43,21 +47,28 @@ public void init() {
public void handleGet(ActionParameters params) throws ActionException {
final JSONObject response;
long id = getId(params);
long limit = params.getHttpParam(PARAM_LIMIT, 0);
long offset = params.getHttpParam(PARAM_OFFSET, 0);
String search = params.getHttpParam(PARAM_SEARCH);
try {
if (id > -1) {
LOG.debug("handleGet: has id", id);
User user = userService.getUser(id);
response = user2Json(user);
} else {
LOG.debug("handleGet: no id");
List<User> users = userService.getUsers();

LOG.debug("Found: " + users.size() + "users");
response = new JSONObject();
JSONArray arr = new JSONArray();
response.put("users", arr);

List<User> newUsers = userService.getUsersWithRoles();
List<User> newUsers = userService.getUsersWithRoles(limit, offset, search);

if (search != null && search.trim() != "") {
response.put("total_count", userService.getUserSearchCount(search));
} else {
response.put("total_count", userService.getUserCount());
}

for (User user : newUsers) {
arr.put(user2Json(user));
}
Expand Down Expand Up @@ -85,15 +96,22 @@ public void handlePost(ActionParameters params) throws ActionException {
LOG.debug("roles size: " + roles.length);
retUser = userService.modifyUserwithRoles(user, roles);
LOG.debug("done modifying user");
if (password != null && !"".equals(password.trim())) {
userService.updateUserPassword(retUser.getScreenname(), password);
if (password != null && !password.trim().isEmpty()) {
if (!UserHelper.isPasswordOk(password)) {
throw new ActionParamsException("Password too weak");
} else {
userService.updateUserPassword(retUser.getScreenname(), password);
}
}
audit.updated(AuditLog.ResourceType.USER);
} else {
LOG.debug("NOW IN POST and creating a new user!!!!!!!!!!!!!");
if (password == null || password.trim().isEmpty()) {
throw new ActionException("Parameter 'password' not found.");
}
if (!UserHelper.isPasswordOk(password)) {
throw new ActionParamsException("Password too weak");
}
retUser = userService.createUser(user);
userService.setUserPassword(retUser.getScreenname(), password);
audit.added(AuditLog.ResourceType.USER);
Expand All @@ -119,6 +137,11 @@ public void handlePut(ActionParameters params) throws ActionException {
String password = params.getRequiredParam(PARAM_PASSWORD);
String[] roles = params.getRequest().getParameterValues("roles");
User retUser = null;

if (!UserHelper.isPasswordOk(password)) {
throw new ActionParamsException("Password too weak");
}

try {
retUser = userService.createUser(user, roles);
userService.setUserPassword(retUser.getScreenname(), password);
Expand All @@ -140,18 +163,14 @@ public void handlePut(ActionParameters params) throws ActionException {
@Override
public void handleDelete(ActionParameters params) throws ActionException {
LOG.debug("handleDelete");
long id = getId(params);
if (id > -1) {
try {
userService.deleteUser(id);
AuditLog.user(params.getClientIp(), params.getUser())
.withParam("id", id)
.deleted(AuditLog.ResourceType.USER);
} catch (ServiceException se) {
throw new ActionException(se.getMessage(), se);
}
} else {
throw new ActionException("Parameter 'id' not found.");
long id = params.getRequiredParamLong(PARAM_ID);
try {
userService.deleteUser(id);
AuditLog.user(params.getClientIp(), params.getUser())
.withParam("id", id)
.deleted(AuditLog.ResourceType.USER);
} catch (ServiceException se) {
throw new ActionException(se.getMessage(), se);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import fi.nls.oskari.annotation.OskariActionRoute;
import fi.nls.oskari.control.*;
import fi.nls.oskari.control.users.model.EmailToken;
import fi.nls.oskari.control.users.model.PasswordRules;
import org.oskari.user.util.UserHelper;
import fi.nls.oskari.control.users.service.MailSenderService;
import fi.nls.oskari.control.users.service.UserRegistrationService;
import fi.nls.oskari.log.LogFactory;
Expand Down Expand Up @@ -76,7 +76,7 @@ public void preProcess(ActionParameters params) throws ActionException {
@Override
public void handleGet(ActionParameters params) throws ActionException {
try {
ResponseHelper.writeResponse(params, mapper.writeValueAsString(PasswordRules.asMap()));
ResponseHelper.writeResponse(params, mapper.writeValueAsString(UserHelper.getPasswordRequirements()));
} catch (JsonProcessingException e) {
ResponseHelper.writeError(params, "Couldn't serialize requirements");
}
Expand All @@ -91,7 +91,7 @@ public void handlePost(ActionParameters params) throws ActionException {
email = params.getRequiredParam(PARAM_EMAIL);
}
// validate email
if(!RegistrationUtil.isValidEmail(email)) {
if(!UserHelper.isValidEmail(email)) {
throw new ActionParamsException(getMessage("user.registration.error.invalidEmail", params.getLocale().getLanguage()));
}
// add or update token
Expand Down Expand Up @@ -123,7 +123,7 @@ public void handlePut(ActionParameters params) throws ActionException {
final EmailToken token = parseContentForEmailUpdate(params);
String username = registerTokenService.findUsernameForEmail(token.getEmail());

if(!RegistrationUtil.isPasswordOk(token.getPassword())) {
if(!UserHelper.isPasswordOk(token.getPassword())) {
throw new ActionParamsException("Password too weak");
}
if (username == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
package fi.nls.oskari.control.users;

import fi.nls.oskari.control.ActionParameters;
import fi.nls.oskari.control.users.model.PasswordRules;
import fi.nls.oskari.util.PropertyUtil;

import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.regex.Pattern;

/**
* Created by SMAKINEN on 1.9.2016.
*/
public class RegistrationUtil {

// From: https://owasp.org/www-community/OWASP_Validation_Regex_Repository
private static final String EMAIL_REGEXP = "^[a-zA-Z0-9_+&*-]+(?:\\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\\.)+[a-zA-Z]{2,}$";
private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEXP);
public static final String getServerAddress(ActionParameters params) {
final String domain = PropertyUtil.get("oskari.domain", null);
if(domain != null) {
Expand All @@ -26,23 +21,6 @@ public static final String getServerAddress(ActionParameters params) {
return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort();
}

public static boolean isValidEmail(String email) {
return email != null && !email.isEmpty() && EMAIL_PATTERN.matcher(email).matches();
}

public static boolean isPasswordOk(String passwd) {
if (passwd == null) {
return false;
}
if (passwd.length() < PasswordRules.getMinLength()) {
return false;
}
if (PasswordRules.getRequireCase() &&
(passwd.toLowerCase().equals(passwd) || passwd.toUpperCase().equals(passwd))) {
return false;
}
return true;
}
/**
* Create timestamp for 2 days as expirytime.
* @return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import fi.nls.oskari.util.ResponseHelper;
import org.oskari.log.AuditLog;
import org.json.JSONObject;
import org.oskari.user.util.UserHelper;

import java.util.Iterator;
import java.util.Map;
Expand Down Expand Up @@ -69,7 +70,7 @@ public void handlePost(ActionParameters params) throws ActionException {
}
final String uuid = params.getRequiredParam("uuid");
final String password = params.getRequiredParam("password");
if(!RegistrationUtil.isPasswordOk(password)) {
if(!UserHelper.isPasswordOk(password)) {
throw new ActionParamsException("Password too weak");
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import fi.nls.oskari.control.ActionParameters;
import fi.nls.oskari.control.users.RegistrationUtil;
import fi.nls.oskari.control.users.model.EmailToken;
import fi.nls.oskari.control.users.model.PasswordRules;
import org.oskari.user.util.UserHelper;
import fi.nls.oskari.control.users.service.MailSenderService;
import fi.nls.oskari.control.users.service.UserRegistrationService;
import fi.nls.oskari.domain.User;
Expand Down Expand Up @@ -71,7 +71,7 @@ public String initRegistration(Model model, @OskariParam ActionParameters params
User user = new User();
user.setScreenname("");
user.setEmail(params.getHttpParam("email"));
if(!RegistrationUtil.isValidEmail(user.getEmail())) {
if(!UserHelper.isValidEmail(user.getEmail())) {
model.addAttribute("error", "user.registration.error.invalidEmail");
return "init_registration";
}
Expand Down Expand Up @@ -132,7 +132,7 @@ public String register(Model model, @PathVariable String uuid, @OskariParam Acti
return index(model, params);
}
model.addAttribute("uuid", uuid);
model.addAttribute("requirements", PasswordRules.asMap());
model.addAttribute("requirements", UserHelper.getPasswordRequirements());
model.addAttribute("email", emailToken.getEmail());
return "new_user";
}
Expand Down Expand Up @@ -179,7 +179,7 @@ public String resetPassword(Model model, @PathVariable String uuid) {
String username = emailService.findUsernameForEmail(emailToken.getEmail());
model.addAttribute("username", username);
model.addAttribute("uuid", emailToken.getUuid());
model.addAttribute("requirements", PasswordRules.asMap());
model.addAttribute("requirements", UserHelper.getPasswordRequirements());
return "passwordReset";

}
Expand Down
28 changes: 28 additions & 0 deletions service-base/src/main/java/fi/nls/oskari/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,34 @@ public List<User> getUsersWithRoles() throws ServiceException {
return Collections.emptyList();
}

/**
* Return count of all users
* @return
* @throws ServiceException
*/
public Long getUserCount() throws ServiceException {
return 0L;
}

/**
* Return count of all users when using search
* @return
* @throws ServiceException
*/
public Long getUserSearchCount(String search) throws ServiceException {
return 0L;
}

/**
* Return all users using pagination & search. This method should be overridden in concrete implementation. The
* default implementation always throws an exception.
* @return List<User> users
* @throws ServiceException
*/
public List<User> getUsersWithRoles(long limit, long offset, String search) throws ServiceException {
return Collections.emptyList();
}

/**
* Create a new user. This method should be overridden in concrete implementation. The
* default implementation always throws an exception.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import java.util.*;


public class DatabaseUserService extends UserService {
private MybatisRoleService roleService = new MybatisRoleService();
private MybatisUserService userService = new MybatisUserService();
Expand Down Expand Up @@ -110,6 +111,34 @@ public List<User> getUsersWithRoles() throws ServiceException {
return newUserList;
}

@Override
public List<User> getUsersWithRoles(long limit, long offset, String search) throws ServiceException {
log.info("getUsersWithRoles");
List<User> users = userService.findAll(limit, offset, search);

List<User> newUserList = new ArrayList<User>();

for(User user : users){
log.debug("userid: " + user.getId());
List<Role> roles = roleService.findByUserId(user.getId());
Set<Role> hashsetRoles = new HashSet<Role>(roles);
user.setRoles(hashsetRoles);
newUserList.add(user);
}

return newUserList;
}

@Override
public Long getUserCount() throws ServiceException {
return userService.findUserCount();
}

@Override
public Long getUserSearchCount(String search) throws ServiceException {
return userService.findUserSearchCount(search);
}

@Override
public User createUser(User user) throws ServiceException {
log.debug("createUser #######################");
Expand Down
Loading

0 comments on commit ea0b5d3

Please sign in to comment.