From b3e3e9bd708a06e3f894a1cc84b55e4926b23bd0 Mon Sep 17 00:00:00 2001 From: catalry Date: Fri, 21 Feb 2020 14:31:59 +0100 Subject: [PATCH 1/3] solved the 2 firsts --- .../controller/AddressBookController.java | 16 +++---- .../ec/survey/service/AttendeeService.java | 44 +++++++++++++------ .../WEB-INF/views/addressbook/addressbook.jsp | 2 +- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/ec/survey/controller/AddressBookController.java b/src/main/java/com/ec/survey/controller/AddressBookController.java index 922406944..261a96289 100644 --- a/src/main/java/com/ec/survey/controller/AddressBookController.java +++ b/src/main/java/com/ec/survey/controller/AddressBookController.java @@ -1,5 +1,6 @@ package com.ec.survey.controller; +import com.ec.survey.exception.ForbiddenURLException; import com.ec.survey.exception.MessageException; import com.ec.survey.model.Paging; import com.ec.survey.model.ParticipationGroup; @@ -70,7 +71,6 @@ public class AddressBookController extends BasicController { @SuppressWarnings("unchecked") @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD}) public ModelAndView attendees(HttpServletRequest request) throws Exception { - User user = sessionService.getCurrentUser(request); int ownerId; if (user.getGlobalPrivileges().get(GlobalPrivilege.ContactManagement) == 2) @@ -132,9 +132,7 @@ public ModelAndView attendees(HttpServletRequest request) throws Exception { if (request.getParameter("added") != null) { - Attendee addedContact = attendeeService.get(Integer.parseInt(request.getParameter("added"))); result.addObject("added", true); - result.addObject("addedContact", addedContact); } else if (request.getParameter("edited") != null && request.getParameter("edited").length() > 0) { if (!request.getParameter("edited").equalsIgnoreCase("batch")) @@ -1316,12 +1314,9 @@ public String delete(@RequestParam("id") String id, HttpServletRequest request) @SuppressWarnings("unchecked") @RequestMapping( value = "/editAttendee/{id}", method = {RequestMethod.GET, RequestMethod.HEAD}) public ModelAndView edit(@PathVariable("id") String id, HttpServletRequest request) throws Exception { - Attendee attendee = attendeeService.get(Integer.parseInt(id)); - Paging paging = (Paging) request.getSession().getAttribute("attendees-paging"); HashMap filter = (HashMap) request.getSession().getAttribute("attendees-filter"); - User user = sessionService.getCurrentUser(request); int ownerId; @@ -1330,8 +1325,13 @@ public ModelAndView edit(@PathVariable("id") String id, HttpServletRequest reque { ownerId = -1; } else { - ownerId = user.getId(); - } + ownerId = user.getId(); + if (attendee.getOwnerId() != ownerId) { + if (!attendeeService.getAccessibleAttendees(ownerId, null).contains(ownerId)) { + throw new ForbiddenURLException(); + } + } + } paging.setItems(attendeeService.getAttendees(ownerId, filter, paging.getCurrentPage(), paging.getItemsPerPage())); diff --git a/src/main/java/com/ec/survey/service/AttendeeService.java b/src/main/java/com/ec/survey/service/AttendeeService.java index 4334846cd..43e4dd40f 100644 --- a/src/main/java/com/ec/survey/service/AttendeeService.java +++ b/src/main/java/com/ec/survey/service/AttendeeService.java @@ -175,22 +175,38 @@ public int getNumberOfAttendees(Integer ownerId, HashMap attribu return ConversionTools.getValue(query.uniqueResult()); } + + @Transactional(readOnly = true) + @SuppressWarnings("unchecked") + public List getAccessibleAttendees(Integer ownerId, HashMap attributeFilter) throws Exception { + Session session = sessionFactory.getCurrentSession(); + + HashMap parameters = new HashMap<>(); + String sql = getSql(session, ownerId, attributeFilter, parameters, false); + + SQLQuery query = session.createSQLQuery("SELECT a.ATTENDEE_ID " + sql); + sqlQueryService.setParameters(query, parameters); + + @SuppressWarnings("rawtypes") + List res = query.list(); + return res; + } - private String getSql(Session session, Integer ownerId, Map hashMap, HashMap oQueryParameters, boolean onlywritableshares) { + private String getSql(Session session, Integer ownerId, Map attributeFilter, HashMap oQueryParameters, boolean onlywritableshares) { StringBuilder sql = new StringBuilder("FROM ATTENDEE a"); - if (hashMap != null && hashMap.size() > 0) + if (attributeFilter != null && attributeFilter.size() > 0) { - for (String key : hashMap.keySet()) + for (String key : attributeFilter.keySet()) { - if (!key.equalsIgnoreCase("name") && !key.equalsIgnoreCase("email") && !key.equalsIgnoreCase("owner") && !key.equalsIgnoreCase("_csrf") && !key.startsWith("visibleAttendee") && hashMap.get(key) != null && hashMap.get(key).trim().length() > 0) + if (!key.equalsIgnoreCase("name") && !key.equalsIgnoreCase("email") && !key.equalsIgnoreCase("owner") && !key.equalsIgnoreCase("_csrf") && !key.startsWith("visibleAttendee") && attributeFilter.get(key) != null && attributeFilter.get(key).trim().length() > 0) { sql.append(" LEFT OUTER JOIN ATTRIBUTE at ON at.ATTE_ID = a.ATTENDEE_ID "); break; } } - if (hashMap.containsKey("owner") && hashMap.get("owner") != null && hashMap.get("owner").length() > 0) + if (attributeFilter.containsKey("owner") && attributeFilter.get("owner") != null && attributeFilter.get("owner").length() > 0) { sql.append(" JOIN USERS u ON u.USER_ID = a.OWNER_ID "); } @@ -212,15 +228,15 @@ private String getSql(Session session, Integer ownerId, Map hash sql.append(" AND a.ATTENDEE_HIDDEN IS NULL"); - if (hashMap != null && hashMap.size() > 0) + if (attributeFilter != null && attributeFilter.size() > 0) { int counter = 0; - for (String key : hashMap.keySet()) + for (String key : attributeFilter.keySet()) { if (!key.equalsIgnoreCase("name") && !key.equalsIgnoreCase("email") && !key.equalsIgnoreCase("owner")) try { int intKey = Integer.parseInt(key); - String value = hashMap.get(key).trim(); + String value = attributeFilter.get(key).trim(); if (value.length() > 0) { @@ -234,22 +250,22 @@ private String getSql(Session session, Integer ownerId, Map hash } } - if (hashMap.containsKey("name") && hashMap.get("name") != null && hashMap.get("name").length() > 0) + if (attributeFilter.containsKey("name") && attributeFilter.get("name") != null && attributeFilter.get("name").length() > 0) { sql.append(" AND a.ATTENDEE_NAME like :name"); - oQueryParameters.put("name", "%" + hashMap.get("name") + "%"); + oQueryParameters.put("name", "%" + attributeFilter.get("name") + "%"); } - if (hashMap.containsKey("email") && hashMap.get("email") != null && hashMap.get("email").length() > 0) + if (attributeFilter.containsKey("email") && attributeFilter.get("email") != null && attributeFilter.get("email").length() > 0) { sql.append(" AND a.ATTENDEE_EMAIL like :email"); - oQueryParameters.put("email", "%" + hashMap.get("email") + "%"); + oQueryParameters.put("email", "%" + attributeFilter.get("email") + "%"); } - if (hashMap.containsKey("owner") && hashMap.get("owner") != null && hashMap.get("owner").length() > 0) + if (attributeFilter.containsKey("owner") && attributeFilter.get("owner") != null && attributeFilter.get("owner").length() > 0) { sql.append(" AND (u.USER_DISPLAYNAME like :owner OR u.USER_LOGIN like :owner)"); - oQueryParameters.put("owner", "%" + hashMap.get("owner") + "%"); + oQueryParameters.put("owner", "%" + attributeFilter.get("owner") + "%"); } } diff --git a/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp b/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp index 984af84f4..9c2c1a8f4 100644 --- a/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp +++ b/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp @@ -881,7 +881,7 @@ From 63e5ed57a2a066f6e7c0b87314d5595cda8f2c16 Mon Sep 17 00:00:00 2001 From: catalry Date: Fri, 21 Feb 2020 18:02:39 +0100 Subject: [PATCH 2/3] ESURVEY-6660 : last and 3d requirement --- .../survey/controller/SettingsController.java | 47 ++++++++++++++----- .../ec/survey/model/administration/User.java | 18 +++++++ .../WEB-INF/classes/messages_en.properties | 2 + .../WEB-INF/views/addressbook/addressbook.jsp | 2 + .../webapp/WEB-INF/views/settings/shares.jsp | 1 + src/main/webapp/resources/js/addressbook.js | 4 +- src/main/webapp/resources/js/shares.js | 3 ++ 7 files changed, 65 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/ec/survey/controller/SettingsController.java b/src/main/java/com/ec/survey/controller/SettingsController.java index d58444924..60d2dd7c4 100644 --- a/src/main/java/com/ec/survey/controller/SettingsController.java +++ b/src/main/java/com/ec/survey/controller/SettingsController.java @@ -1,5 +1,6 @@ package com.ec.survey.controller; +import com.ec.survey.exception.ForbiddenURLException; import com.ec.survey.model.administration.GlobalPrivilege; import com.ec.survey.model.administration.User; import com.ec.survey.model.attendees.Attendee; @@ -29,6 +30,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; @@ -48,7 +50,7 @@ public class SettingsController extends BasicController { @Resource(name="attendeeService") private AttendeeService attendeeService; - + @Autowired private LocaleResolver localeResolver; @RequestMapping(method = {RequestMethod.GET, RequestMethod.HEAD}) @@ -285,19 +287,42 @@ public ModelAndView shareEdit(@PathVariable String pid, HttpServletRequest reque } @RequestMapping(value = "/userExists", headers="Accept=*/*", method=RequestMethod.GET) - public @ResponseBody boolean userExists(HttpServletRequest request, HttpServletResponse response ) { + public @ResponseBody boolean userExists(HttpServletRequest request, HttpServletResponse response ) + throws NotAgreedToTosException, WeakAuthenticationException, ForbiddenURLException { HashMap parameters = Ucs2Utf8.requestToHashMap(request); - - String login = parameters.get("login")[0]; - - User user; - try { - user = administrationService.getUserForLogin(login); - } catch (Exception e) { - return false; + User userInRequest = sessionService.getCurrentUser(request); + User user = administrationService.getUser(userInRequest.getId()); + Date now = new Date(); + Date lastAttemptMoment = new Date(); + if (user.getUserExistsAttemptDate() != null) { + lastAttemptMoment = user.getUserExistsAttemptDate(); + } else { + user.setUserExistsAttemptDate(now); } - return user != null; + long lastAttemptMomentPlusOneHourLong = lastAttemptMoment.getTime() + 1000L * 60L * 60L; + Date lastAttemptMomentPlusOneHour = new Date(lastAttemptMomentPlusOneHourLong); + int numberOfAttemptsInOneHour = user.getUserExistsAttempts(); + if (now.after(lastAttemptMomentPlusOneHour)) { + // reinit + numberOfAttemptsInOneHour = 1; + user.setUserExistsAttempts(numberOfAttemptsInOneHour); + user.setUserExistsAttemptDate(now); + } else { + // adding + numberOfAttemptsInOneHour += 1; + user.setUserExistsAttempts(numberOfAttemptsInOneHour); + if (numberOfAttemptsInOneHour > 30) { + throw new ForbiddenURLException(); + // not saving the user since this would overload the Users table + } + } + administrationService.updateUser(user); + sessionService.setCurrentUser(request, user); + + String login = parameters.get("login")[0]; + User searchedUser = administrationService.getUserForLogin(login); + return searchedUser != null; } @RequestMapping(value = "/createStaticShare", method = RequestMethod.POST) diff --git a/src/main/java/com/ec/survey/model/administration/User.java b/src/main/java/com/ec/survey/model/administration/User.java index 2c3ccb9ea..a4a005748 100644 --- a/src/main/java/com/ec/survey/model/administration/User.java +++ b/src/main/java/com/ec/survey/model/administration/User.java @@ -46,6 +46,8 @@ public class User implements java.io.Serializable { private Date validationCodeGeneration; private List departments = new ArrayList<>(); private int badLoginAttempts = 0; + private int userExistsAttempts = 0; + private Date userExistsAttemptDate; private boolean agreedToToS; private Integer lastEditedSurvey; private boolean canCreateSurveys = true; @@ -271,6 +273,22 @@ public int getBadLoginAttempts() { public void setBadLoginAttempts(Integer badLoginAttempts) { this.badLoginAttempts = badLoginAttempts != null ? badLoginAttempts : 0; } + + @Column(name = "USER_EXISTS_ATTEMPS") + public int getUserExistsAttempts() { + return this.userExistsAttempts; + } + public void setUserExistsAttempts(Integer userExistsAttempts) { + this.userExistsAttempts = userExistsAttempts != null ? userExistsAttempts : 0; + } + + @Column(name = "USER_EXISTS_ATTEMPT_DATE") + public Date getUserExistsAttemptDate() { + return userExistsAttemptDate; + } + public void setUserExistsAttemptDate(Date userExistsAttemptDate) { + this.userExistsAttemptDate = userExistsAttemptDate; + } @Column(name = "USER_TOS") public boolean isAgreedToToS() { diff --git a/src/main/webapp/WEB-INF/classes/messages_en.properties b/src/main/webapp/WEB-INF/classes/messages_en.properties index 54853e4bb..1d9295cc5 100644 --- a/src/main/webapp/WEB-INF/classes/messages_en.properties +++ b/src/main/webapp/WEB-INF/classes/messages_en.properties @@ -142,6 +142,8 @@ error.nouserselected = Please select a user error.OwnerNotValid = The selected owner is not a valid user error.PasswordWeak = Please choose a password between 8 and 16 characters with at least one digit and one non-alphanumeric character (e.g. !?$%...). error.PleaseReload = There was a problem. Please reload the page. +error.UsersTooOftenAddressBook = You have exceeded the number of contact edits you may perform per hour. +error.UsersTooOftenShares = You have exceeded the number of shares you may perform per hour. error.RequestTranslation = Request for translation failed error.ResetCodeInvalid = You did not provide a valid password reset code! error.ResetCodeOutdated = This password reset code is not valid anymore! Please request a new one. diff --git a/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp b/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp index 9c2c1a8f4..d0e1a610a 100644 --- a/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp +++ b/src/main/webapp/WEB-INF/views/addressbook/addressbook.jsp @@ -16,6 +16,7 @@ +