Merge branch 'develop'

This commit is contained in:
Paulo Gustavo Veiga 2022-02-16 18:41:21 -08:00
commit c84a583c3f
27 changed files with 165 additions and 254 deletions

View File

@ -10,7 +10,7 @@ ARG WEBAPP_TARGET_DIR="/usr/local/tomcat/webapps/ROOT"
ARG DB_BASE_DIR="/var/lib/wisemapping" ARG DB_BASE_DIR="/var/lib/wisemapping"
# Defautl ENV configurations ... # Defautl ENV configurations ...
ENV JAVA_OPTS="-XX:+PrintFlagsFinal -XX:InitialRAMPercentage=30 -XX:MaxRAMPercentage=80" ENV JAVA_OPTS="-XX:+PrintFlagsFinal -XX:InitialRAMPercentage=30 -XX:MaxRAMPercentage=80 -javaagent:/opt/newrelic/newrelic.jar"
ENV database.base.url=${DB_BASE_DIR} ENV database.base.url=${DB_BASE_DIR}
# Copy wisemapping distribution ... # Copy wisemapping distribution ...

View File

@ -29,11 +29,11 @@
<mkdir dir="target/wisemapping-mindplot"/> <mkdir dir="target/wisemapping-mindplot"/>
<exec executable="npm" dir="target"> <exec executable="npm" dir="target">
<arg value="pack"/> <arg value="pack"/>
<arg value="@wisemapping/mindplot@5.0.3"/> <arg value="@wisemapping/mindplot@5.0.5"/>
</exec> </exec>
<exec executable="tar" dir="target"> <exec executable="tar" dir="target">
<arg value="-xvzf"/> <arg value="-xvzf"/>
<arg value="wisemapping-mindplot-5.0.4.tgz"/> <arg value="wisemapping-mindplot-5.0.5.tgz"/>
<arg value="-C"/> <arg value="-C"/>
<arg value="wisemapping-mindplot"/> <arg value="wisemapping-mindplot"/>
</exec> </exec>
@ -42,11 +42,11 @@
<mkdir dir="target/wisemapping-webapp"/> <mkdir dir="target/wisemapping-webapp"/>
<exec executable="npm" dir="target"> <exec executable="npm" dir="target">
<arg value="pack"/> <arg value="pack"/>
<arg value="@wisemapping/webapp@5.0.3"/> <arg value="@wisemapping/webapp@5.0.6"/>
</exec> </exec>
<exec executable="tar" dir="target"> <exec executable="tar" dir="target">
<arg value="-xvzf"/> <arg value="-xvzf"/>
<arg value="wisemapping-webapp-5.0.4.tgz"/> <arg value="wisemapping-webapp-5.0.6.tgz"/>
<arg value="-C"/> <arg value="-C"/>
<arg value="wisemapping-webapp"/> <arg value="wisemapping-webapp"/>
</exec> </exec>

View File

@ -12,25 +12,10 @@
<version>5.0.4</version> <version>5.0.4</version>
</parent> </parent>
<repositories>
<repository>
<id>maven2-repository.dev.java.net</id>
<name>Java.net Repository for Maven</name>
<url>http://download.java.net/maven/2/</url>
<layout>default</layout>
</repository>
<repository>
<id>maven2-repository.jahia.org</id>
<name>Jahia Repository for Maven</name>
<url>http://maven.jahia.org/maven2/</url>
<layout>default</layout>
</repository>
</repositories>
<properties> <properties>
<org.springframework.version>5.3.14</org.springframework.version> <org.springframework.version>5.3.14</org.springframework.version>
<org.springframework.addons>5.3.5.RELEASE</org.springframework.addons> <org.springframework.addons>5.3.5.RELEASE</org.springframework.addons>
<hibernate.version>5.6.3.Final</hibernate.version> <hibernate.version>5.6.5.Final</hibernate.version>
<hibernate-validator.version>6.0.21.Final</hibernate-validator.version> <hibernate-validator.version>6.0.21.Final</hibernate-validator.version>
</properties> </properties>
@ -205,7 +190,7 @@
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version> <version>8.0.28</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -213,12 +198,6 @@
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version> <version>2.9.0</version>
</dependency> </dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
<scope>runtime</scope>
</dependency>
<dependency> <dependency>
<groupId>org.hibernate</groupId> <groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId> <artifactId>hibernate-ehcache</artifactId>
@ -240,6 +219,12 @@
<version>1.2.17</version> <version>1.2.17</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- https://mvnrepository.com/artifact/commons-validator/commons-validator -->
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.7</version>
</dependency>
<!-- Only for test purposes --> <!-- Only for test purposes -->
<dependency> <dependency>
<groupId>org.hsqldb</groupId> <groupId>org.hsqldb</groupId>
@ -250,7 +235,7 @@
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
<version>2.11.3</version> <version>2.13.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.servlet</groupId> <groupId>javax.servlet</groupId>
@ -277,7 +262,7 @@
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId> <artifactId>fluent-hc</artifactId>
<version>4.5.5</version> <version>4.5.13</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>

View File

@ -102,22 +102,28 @@ public class UserManagerImpl
} }
@Override @Override
public User createUser(@NotNull User user, @NotNull Collaborator col) { public User createUser(@NotNull User user, @NotNull Collaborator collaborator) {
user.setPassword(passwordEncoder.encode(user.getPassword())); this.createUser(user);
assert user != null : "Trying to store a null user";
final Set<Collaboration> set = col.getCollaborations(); // Migrate from previous temporal collab to new user ...
for (Collaboration collaboration : set) { final Set<Collaboration> collaborations = collaborator.getCollaborations();
Collaboration newMapUser = new Collaboration(); for (Collaboration oldCollab : collaborations) {
newMapUser.setRoleId(collaboration.getRole().ordinal()); Collaboration newCollab = new Collaboration();
newMapUser.setMindMap(collaboration.getMindMap()); newCollab.setRoleId(oldCollab.getRole().ordinal());
newMapUser.setCollaborator(user); newCollab.setMindMap(oldCollab.getMindMap());
user.addCollaboration(newMapUser); newCollab.setCollaborator(user);
user.addCollaboration(newCollab);
getHibernateTemplate().save(newCollab);
// Delete collaborations on this collaborator ...
getHibernateTemplate().delete(oldCollab);
} }
getHibernateTemplate().delete(col); // Delete collaboration ...
getHibernateTemplate().delete(collaborator);
getHibernateTemplate().flush(); getHibernateTemplate().flush();
getHibernateTemplate().saveOrUpdate(user); getHibernateTemplate().saveOrUpdate(user);
return user; return user;
} }
@ -136,8 +142,7 @@ public class UserManagerImpl
// Does the password need to be encrypted ? // Does the password need to be encrypted ?
final String password = user.getPassword(); final String password = user.getPassword();
if(password!=null && (!password.startsWith(LegacyPasswordEncoder.ENC_PREFIX) && !password.startsWith( "{"+ DefaultPasswordEncoderFactories.ENCODING_ID))) if (password != null && (!password.startsWith(LegacyPasswordEncoder.ENC_PREFIX) && !password.startsWith("{" + DefaultPasswordEncoderFactories.ENCODING_ID))) {
{
user.setPassword(passwordEncoder.encode(user.getPassword())); user.setPassword(passwordEncoder.encode(user.getPassword()));
} }
@ -152,7 +157,7 @@ public class UserManagerImpl
query.setParameter("activationCode", code); query.setParameter("activationCode", code);
final List users = query.list(); final List users = query.list();
if(users != null && !users.isEmpty()) { if (users != null && !users.isEmpty()) {
assert users.size() == 1 : "More than one user with the same username!"; assert users.size() == 1 : "More than one user with the same username!";
user = (User) users.get(0); user = (User) users.get(0);

View File

@ -41,7 +41,7 @@ public final class Mailer {
//~ Methods .............................................................................................. //~ Methods ..............................................................................................
public Mailer(@NotNull String siteEmail, @NotNull String supportEmail,@NotNull String errorReporterEmail) { public Mailer(@NotNull String siteEmail, @NotNull String supportEmail, @NotNull String errorReporterEmail) {
this.serverFromEmail = siteEmail; this.serverFromEmail = siteEmail;
this.supportEmail = supportEmail; this.supportEmail = supportEmail;
this.errorReporterEmail = errorReporterEmail; this.errorReporterEmail = errorReporterEmail;
@ -51,7 +51,7 @@ public final class Mailer {
return serverFromEmail; return serverFromEmail;
} }
public void sendEmail(final String from, final String to, final String subject, final Map model, public void sendEmail(final String from, final String to, final String subject, final Map<String, Object> model,
@NotNull final String templateMail) { @NotNull final String templateMail) {
final MimeMessagePreparator preparator = final MimeMessagePreparator preparator =
new MimeMessagePreparator() { new MimeMessagePreparator() {

View File

@ -22,6 +22,7 @@ import com.wisemapping.filter.SupportedUserAgent;
import com.wisemapping.model.Collaboration; import com.wisemapping.model.Collaboration;
import com.wisemapping.model.Mindmap; import com.wisemapping.model.Mindmap;
import com.wisemapping.model.User; import com.wisemapping.model.User;
import com.wisemapping.rest.model.RestLogItem;
import com.wisemapping.util.VelocityEngineUtils; import com.wisemapping.util.VelocityEngineUtils;
import com.wisemapping.util.VelocityEngineWrapper; import com.wisemapping.util.VelocityEngineWrapper;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
@ -140,7 +141,7 @@ final public class NotificationService {
public void activateAccount(@NotNull User user) { public void activateAccount(@NotNull User user) {
final Map<String, User> model = new HashMap<>(); final Map<String, Object> model = new HashMap<>();
model.put("user", user); model.put("user", user);
mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "[WiseMapping] Active account", model, "activationAccountMail.vm"); mailer.sendEmail(mailer.getServerSenderEmail(), user.getEmail(), "[WiseMapping] Active account", model, "activationAccountMail.vm");
} }
@ -163,19 +164,24 @@ final public class NotificationService {
this.velocityEngineWrapper = engine; this.velocityEngineWrapper = engine;
} }
public void reportJavascriptException(@Nullable Mindmap mindmap, @Nullable User user, @Nullable String jsErrorMsg, @NotNull HttpServletRequest request) { public void reportJavascriptException(@Nullable Mindmap mindmap, @Nullable User user, @NotNull RestLogItem errorItem, @NotNull HttpServletRequest request) {
final Map<String, String> model = new HashMap<>(); final Map<String, String> summary = new HashMap<>();
model.put("errorMsg", jsErrorMsg); summary.put("JS-MSG", errorItem.getJsErrorMsg());
summary.put("JS-STACK", errorItem.getJsStack());
String mindmapXML = "";
try { try {
model.put("mapXML", StringEscapeUtils.escapeXml(mindmap == null ? "map not found" : mindmap.getXmlStr())); mindmapXML = StringEscapeUtils.escapeXml(mindmap == null ? "map not found" : mindmap.getXmlStr());
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
// Ignore ... // Ignore ...
} }
model.put("mapId", Integer.toString(mindmap.getId())); summary.put("mapId", Integer.toString(mindmap.getId()));
model.put("mapTitle", mindmap.getTitle()); summary.put("mapTitle", mindmap.getTitle());
logError(model, user, request); logError(summary, user, request);
logger.error("Unexpected editor mindmap => " + mindmapXML);
logger.error("Unexpected editor JS Stack => " + errorItem.getJsErrorMsg() + "-" + errorItem.getJsStack());
} }
private void logError(@NotNull Map<String, String> model, @Nullable User user, @NotNull HttpServletRequest request) { private void logError(@NotNull Map<String, String> model, @Nullable User user, @NotNull HttpServletRequest request) {
@ -193,7 +199,7 @@ final public class NotificationService {
.map(key -> key + "=" + model.get(key)) .map(key -> key + "=" + model.get(key))
.collect(Collectors.joining(", ", "{", "}")); .collect(Collectors.joining(", ", "{", "}"));
logger.error("Unexpected editor error => " + errorAsString); logger.error("Unexpected editor info => " + errorAsString);
} }
public void reportJavaException(@NotNull Throwable exception, @Nullable User user, @NotNull HttpServletRequest request) { public void reportJavaException(@NotNull Throwable exception, @Nullable User user, @NotNull HttpServletRequest request) {

View File

@ -1,24 +1,27 @@
/* /*
* Copyright [2015] [wisemapping] * Copyright [2015] [wisemapping]
* *
* Licensed under WiseMapping Public License, Version 1.0 (the "License"). * Licensed under WiseMapping Public License, Version 1.0 (the "License").
* It is basically the Apache License, Version 2.0 (the "License") plus the * It is basically the Apache License, Version 2.0 (the "License") plus the
* "powered by wisemapping" text requirement on every single page; * "powered by wisemapping" text requirement on every single page;
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the license at * You may obtain a copy of the license at
* *
* http://www.wisemapping.org/license * http://www.wisemapping.org/license
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.wisemapping.model; package com.wisemapping.model;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import java.io.Serializable; import java.io.Serializable;
@ -29,22 +32,23 @@ public class Collaboration implements Serializable {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;; private int id;
;
@Column(name = "role_id",unique = true,nullable = true) @Column(name = "role_id", unique = true)
private CollaborationRole role; private CollaborationRole role;
@ManyToOne @ManyToOne
@JoinColumn(name="mindmap_id",nullable = false) @JoinColumn(name = "mindmap_id", nullable = false)
private Mindmap mindMap; private Mindmap mindMap;
@ManyToOne(fetch = FetchType.LAZY) @ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name="colaborator_id",nullable = false) @JoinColumn(name = "colaborator_id", nullable = false)
private Collaborator collaborator; private Collaborator collaborator;
@ManyToOne(cascade = CascadeType.ALL) @ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="properties_id",nullable = false, unique = true) @JoinColumn(name = "properties_id", nullable = false, unique = true)
private CollaborationProperties collaborationProperties = new CollaborationProperties();; private CollaborationProperties collaborationProperties = new CollaborationProperties();
public Collaboration() { public Collaboration() {
} }
@ -129,10 +133,9 @@ public class Collaboration implements Serializable {
@Override @Override
public int hashCode() { public int hashCode() {
int result = (int) (id ^ (id >>> 32)); int result = id ^ (id >>> 32);
result = 31 * result + (role != null ? role.hashCode() : 0); result = 31 * result + (role != null ? role.hashCode() : 0);
result = 31 * result + (mindMap != null ? mindMap.hashCode() : 0); result = 31 * result + (mindMap != null ? mindMap.hashCode() : 0);
result = 31 * result + (collaborator != null ? collaborator.hashCode() : 0);
return result; return result;
} }
} }

View File

@ -55,8 +55,6 @@ public class AccountController extends BaseController {
@Autowired @Autowired
private NotificationService notificationService; private NotificationService notificationService;
final Logger logger = Logger.getLogger(AccountController.class);
@RequestMapping(method = RequestMethod.PUT, value = "account/password", consumes = {"text/plain"}) @RequestMapping(method = RequestMethod.PUT, value = "account/password", consumes = {"text/plain"})
@ResponseStatus(value = HttpStatus.NO_CONTENT) @ResponseStatus(value = HttpStatus.NO_CONTENT)
@ -133,8 +131,8 @@ public class AccountController extends BaseController {
public void logError(@RequestBody RestLogItem item, @NotNull HttpServletRequest request) { public void logError(@RequestBody RestLogItem item, @NotNull HttpServletRequest request) {
final Mindmap mindmap = mindmapService.findMindmapById(item.getMapId()); final Mindmap mindmap = mindmapService.findMindmapById(item.getMapId());
final User user = Utils.getUser(); final User user = Utils.getUser();
logger.error("Unexpected editor error - " + item.getJsErrorMsg());
notificationService.reportJavascriptException(mindmap, user, item.getJsErrorMsg() + "\n" + item.getJsStack(), request); notificationService.reportJavascriptException(mindmap, user, item, request);
} }
} }

View File

@ -27,6 +27,7 @@ import com.wisemapping.rest.model.*;
import com.wisemapping.security.Utils; import com.wisemapping.security.Utils;
import com.wisemapping.service.*; import com.wisemapping.service.*;
import com.wisemapping.validator.MapInfoValidator; import com.wisemapping.validator.MapInfoValidator;
import org.apache.commons.validator.routines.EmailValidator;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -296,7 +297,14 @@ public class MindmapController extends BaseController {
// Compare one by one if some of the elements has been changed .... // Compare one by one if some of the elements has been changed ....
final Set<Collaboration> collabsToRemove = new HashSet<>(mindMap.getCollaborations()); final Set<Collaboration> collabsToRemove = new HashSet<>(mindMap.getCollaborations());
for (RestCollaboration restCollab : restCollabs.getCollaborations()) { for (RestCollaboration restCollab : restCollabs.getCollaborations()) {
final Collaboration collaboration = mindMap.findCollaboration(restCollab.getEmail()); final String email = restCollab.getEmail();
// Is a valid email address ?
if (!EmailValidator.getInstance().isValid(email)) {
throw new IllegalArgumentException(email + " is not valid email address");
}
final Collaboration collaboration = mindMap.findCollaboration(email);
// Validate role format ... // Validate role format ...
String roleStr = restCollab.getRole(); String roleStr = restCollab.getRole();
if (roleStr == null) { if (roleStr == null) {
@ -333,6 +341,17 @@ public class MindmapController extends BaseController {
throw new IllegalArgumentException("No enough permissions"); throw new IllegalArgumentException("No enough permissions");
} }
// Is valid email address ?
final EmailValidator emailValidator = EmailValidator.getInstance();
restCollabs
.getCollaborations()
.forEach(collab -> {
// Is a valid email address ?
if (!emailValidator.isValid(collab.getEmail())) {
throw new IllegalArgumentException(collab.getEmail() + " is not valid email address");
}
});
// Has any role changed ?. Just removed it. // Has any role changed ?. Just removed it.
final Map<String, Collaboration> mapsByEmail = mindMap final Map<String, Collaboration> mapsByEmail = mindMap
.getCollaborations() .getCollaborations()
@ -432,6 +451,12 @@ public class MindmapController extends BaseController {
public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws IOException, WiseMappingException { public void deleteCollabByEmail(@PathVariable int id, @RequestParam(required = false) String email) throws IOException, WiseMappingException {
logger.debug("Deleting permission for email:" + email); logger.debug("Deleting permission for email:" + email);
// Is a valid email address ?
final EmailValidator emailValidator = EmailValidator.getInstance();
if (!emailValidator.isValid(email)) {
throw new IllegalArgumentException(email + " is not valid email address");
}
final Mindmap mindmap = findMindmapById(id); final Mindmap mindmap = findMindmapById(id);
final User user = Utils.getUser(); final User user = Utils.getUser();
@ -495,6 +520,7 @@ public class MindmapController extends BaseController {
mindmapService.removeMindmap(mindmap, user); mindmapService.removeMindmap(mindmap, user);
} }
} }
@RequestMapping(method = RequestMethod.POST, value = "/maps", consumes = {"application/xml", "application/json"}) @RequestMapping(method = RequestMethod.POST, value = "/maps", consumes = {"application/xml", "application/json"})
@ResponseStatus(value = HttpStatus.CREATED) @ResponseStatus(value = HttpStatus.CREATED)
public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws IOException, WiseMappingException { public void createMap(@RequestBody(required = false) String mapXml, @NotNull HttpServletResponse response, @RequestParam(required = false) String title, @RequestParam(required = false) String description) throws IOException, WiseMappingException {
@ -506,7 +532,7 @@ public class MindmapController extends BaseController {
if (description != null && !description.isEmpty()) { if (description != null && !description.isEmpty()) {
mindmap.setDescription(description); mindmap.setDescription(description);
}else { } else {
mindmap.setDescription("description"); mindmap.setDescription("description");
} }

View File

@ -58,7 +58,7 @@ public class UserController extends BaseController {
@RequestMapping(method = RequestMethod.POST, value = "/users", produces = {"application/json", "application/xml"}) @RequestMapping(method = RequestMethod.POST, value = "/users", produces = {"application/json", "application/xml"})
@ResponseStatus(value = HttpStatus.CREATED) @ResponseStatus(value = HttpStatus.CREATED)
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws WiseMappingException, BindException { public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws WiseMappingException, BindException {
logger.info("Register new user:" + registration.getEmail()); logger.debug("Register new user:" + registration.getEmail());
// If tomcat is behind a reverse proxy, ip needs to be found in other header. // If tomcat is behind a reverse proxy, ip needs to be found in other header.
String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER); String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER);

View File

@ -156,7 +156,7 @@ public class MindmapServiceImpl
@Override @Override
public void removeMindmap(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException { public void removeMindmap(@NotNull Mindmap mindmap, @NotNull User user) throws WiseMappingException {
if (mindmap.getCreator().identityEquality(user) || isAdmin(user)) { if (mindmap.getCreator().identityEquality(user)) {
mindmapManager.removeMindmap(mindmap); mindmapManager.removeMindmap(mindmap);
} else { } else {
final Optional<Collaboration> collaboration = mindmap.findCollaboration(user); final Optional<Collaboration> collaboration = mindmap.findCollaboration(user);

View File

@ -1,6 +1,7 @@
package com.wisemapping.service; package com.wisemapping.service;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.wisemapping.validator.Messages;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair; import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Form; import org.apache.http.client.fluent.Form;
@ -22,6 +23,8 @@ public class RecaptchaService {
"https://www.google.com/recaptcha/api/siteverify"; "https://www.google.com/recaptcha/api/siteverify";
private final static ObjectMapper objectMapper = new ObjectMapper(); private final static ObjectMapper objectMapper = new ObjectMapper();
public static final String CATCH_ERROR_CODE_TIMEOUT_OR_DUPLICATE = "timeout-or-duplicate";
public static final String CATCHA_ERROR_CODE_INPUT_RESPONSE = "invalid-input-response";
private String recaptchaSecret; private String recaptchaSecret;
@Nullable @Nullable
@ -48,12 +51,21 @@ public class RecaptchaService {
.asBytes(); .asBytes();
final Map responseBody = objectMapper.readValue(body, HashMap.class); final Map responseBody = objectMapper.readValue(body, HashMap.class);
logger.warn("Response from recaptcha after parse: " + responseBody); logger.debug("Response from recaptcha after parse: " + responseBody);
final Boolean success = (Boolean) responseBody.get("success"); final Boolean success = (Boolean) responseBody.get("success");
if (success!=null && !success) { if (success != null && !success) {
final List<String> errorCodes = (List<String>) responseBody.get("error-codes"); final List<String> errorCodes = (List<String>) responseBody.get("error-codes");
result = RecaptchaUtil.codeToDescription(errorCodes.get(0)); String errorCode = errorCodes.get(0);
if (errorCode.equals(CATCH_ERROR_CODE_TIMEOUT_OR_DUPLICATE)) {
result = Messages.CAPTCHA_TIMEOUT_OUT_DUPLICATE;
} else if (errorCode.equals("invalid-input-response")) {
result = Messages.CAPTCHA_INVALID_INPUT_RESPONSE;
} else {
result = Messages.CAPTCHA_LOADING_ERROR;
logger.error("Unexpected error during catch resolution:" + errorCodes);
}
} }
} catch (IOException e) { } catch (IOException e) {
logger.error(e.getMessage(), e); logger.error(e.getMessage(), e);
@ -68,30 +80,4 @@ public class RecaptchaService {
public void setRecaptchaSecret(String recaptchaSecret) { public void setRecaptchaSecret(String recaptchaSecret) {
this.recaptchaSecret = recaptchaSecret; this.recaptchaSecret = recaptchaSecret;
} }
}
class RecaptchaUtil {
private static final Map<String, String>
RECAPTCHA_ERROR_CODE = new HashMap<>();
static String codeToDescription(final String code)
{
return RECAPTCHA_ERROR_CODE.getOrDefault(code,"Unexpected error validating code. Please, refresh the page and try again.");
}
static {
RECAPTCHA_ERROR_CODE.put("missing-input-secret",
"The secret parameter is missing");
RECAPTCHA_ERROR_CODE.put("invalid-input-secret",
"The secret parameter is invalid or malformed");
RECAPTCHA_ERROR_CODE.put("missing-input-response",
"The response parameter is missing");
RECAPTCHA_ERROR_CODE.put("invalid-input-response",
"The response parameter is invalid or malformed");
RECAPTCHA_ERROR_CODE.put("bad-request",
"The request is invalid or malformed");
RECAPTCHA_ERROR_CODE.put("timeout-or-duplicate",
"Please, refresh the page and try again.");
}
} }

View File

@ -119,13 +119,11 @@ public class UserServiceImpl
if (emailConfirmEnabled) { if (emailConfirmEnabled) {
user.setActivationDate(null); user.setActivationDate(null);
} else { } else {
user.setActivationDate(Calendar.getInstance()); user.setActivationDate(Calendar.getInstance());
} }
Collaborator col = userManager.getCollaboratorBy(user.getEmail()); final Collaborator col = userManager.getCollaboratorBy(user.getEmail());
if (col != null) { if (col != null) {
userManager.createUser(user, col); userManager.createUser(user, col);
} else { } else {

View File

@ -26,4 +26,7 @@ public interface Messages {
String LABEL_TITLE_ALREADY_EXISTS = "LABEL_TITLE_ALREADY_EXISTS"; String LABEL_TITLE_ALREADY_EXISTS = "LABEL_TITLE_ALREADY_EXISTS";
String PASSWORD_MISMATCH = "PASSWORD_MISMATCH"; String PASSWORD_MISMATCH = "PASSWORD_MISMATCH";
String CAPTCHA_LOADING_ERROR = "CAPTCHA_LOADING_ERROR"; String CAPTCHA_LOADING_ERROR = "CAPTCHA_LOADING_ERROR";
String CAPTCHA_TIMEOUT_OUT_DUPLICATE = "CAPTCHA_TIMEOUT_OUT_DUPLICATE";
String CAPTCHA_INVALID_INPUT_RESPONSE = "CAPTCHA_INVALID_INPUT_RESPONSE";
} }

View File

@ -18,32 +18,14 @@
package com.wisemapping.webmvc; package com.wisemapping.webmvc;
import com.wisemapping.service.MindmapService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller @Controller
public class PublicPagesController { public class PublicPagesController {
@Qualifier("mindmapService")
@Autowired
private MindmapService mindmapService;
@RequestMapping(value = "keyboard")
public String newsPage() {
return "keyboard";
}
@RequestMapping(value = "home") @RequestMapping(value = "home")
public String home() { public String home() {
return "homepage"; return "homepage";
} }
@RequestMapping(value = "iframeWrapper")
public ModelAndView showIframePage(@RequestParam(required = true) String url) {
return new ModelAndView("iframeWrapper", "url", url);
}
} }

View File

@ -48,4 +48,6 @@ MINDMAP_IS_LOCKED = Mindmap ist für die Bearbeitung gesperrt.
# Confirmed # Confirmed
RESET_PASSWORD_INVALID_EMAIL = Die angegebene E-Mail-Adresse ist kein gültiges Benutzerkonto. Bitte versuchen Sie es erneut mit einer gültigen E-Mail-Adresse. RESET_PASSWORD_INVALID_EMAIL = Die angegebene E-Mail-Adresse ist kein gültiges Benutzerkonto. Bitte versuchen Sie es erneut mit einer gültigen E-Mail-Adresse.
TRY_WELCOME = Dieser Ausgabebereich zeigt einige der Mindmap-Editor-Funktionen \!. TRY_WELCOME = Dieser Ausgabebereich zeigt einige der Mindmap-Editor-Funktionen \!.
UNEXPECTED_ERROR_DETAILS = Unerwarteter Fehler bei der Verarbeitung der Anforderung. UNEXPECTED_ERROR_DETAILS = Unerwarteter Fehler bei der Verarbeitung der Anforderung.
NO_ENOUGH_PERMISSIONS=Diese map ist nicht mehr verfügbar.
NO_ENOUGH_PERMISSIONS_DETAILS=Sie haben nicht die erforderlichen Rechte, um sich diese map anzusehen. Diese map ist entweder privat oder wurde gelöscht.

View File

@ -48,4 +48,8 @@ MINDMAP_IS_LOCKED = Mindmap is locked for edition.
# Confirmed # Confirmed
RESET_PASSWORD_INVALID_EMAIL = The email provided is not a valid user account. Please, try again with a valid email. RESET_PASSWORD_INVALID_EMAIL = The email provided is not a valid user account. Please, try again with a valid email.
TRY_WELCOME = This edition space showcases some of the mindmap editor capabilities \!. TRY_WELCOME = This edition space showcases some of the mindmap editor capabilities \!.
UNEXPECTED_ERROR_DETAILS = Unexpected error processing request. UNEXPECTED_ERROR_DETAILS = Unexpected error processing request.
NO_ENOUGH_PERMISSIONS=This mind map can opened.
NO_ENOUGH_PERMISSIONS_DETAILS=You do not have enough right access to see this map. This map has been changed to private or deleted.
CAPTCHA_TIMEOUT_OUT_DUPLICATE=Please, refresh the page and try again.
CAPTCHA_INVALID_INPUT_RESPONSE="Invalid input response, refresh the page and try again.

View File

@ -48,4 +48,7 @@ MINDMAP_IS_LOCKED = Mindmap está bloqueado para la edición.
# Confirmed # Confirmed
RESET_PASSWORD_INVALID_EMAIL = El correo electrónico proporcionado no es una cuenta de usuario válida. Por favor, intente nuevamente con un correo electrónico válido. RESET_PASSWORD_INVALID_EMAIL = El correo electrónico proporcionado no es una cuenta de usuario válida. Por favor, intente nuevamente con un correo electrónico válido.
TRY_WELCOME = ¡Este espacio de edición muestra algunas de las capacidades del editor de mapas mentales\!. TRY_WELCOME = ¡Este espacio de edición muestra algunas de las capacidades del editor de mapas mentales\!.
UNEXPECTED_ERROR_DETAILS = Error inesperado procesando tu pedido. UNEXPECTED_ERROR_DETAILS = Error inesperado procesando tu pedido.
NO_ENOUGH_PERMISSIONS=El mapa buscado no se encuentra disponible.
NO_ENOUGH_PERMISSIONS_DETAILS=No tiene suficiente permisos de acceso para ver este mapa. El mapa no es mas publico o ha sido borrado.

View File

@ -48,4 +48,6 @@ MINDMAP_IS_LOCKED = Mindmap est verrouillé pour l'édition.
# Confirmed # Confirmed
RESET_PASSWORD_INVALID_EMAIL = L'e-mail fourni n'est pas un compte d'utilisateur valide. Veuillez réessayer avec un e-mail valide. RESET_PASSWORD_INVALID_EMAIL = L'e-mail fourni n'est pas un compte d'utilisateur valide. Veuillez réessayer avec un e-mail valide.
TRY_WELCOME = Cet espace d'édition présente certaines des fonctionnalités de l'éditeur de cartes mentales \!. TRY_WELCOME = Cet espace d'édition présente certaines des fonctionnalités de l'éditeur de cartes mentales \!.
UNEXPECTED_ERROR_DETAILS = Erreur inattendue lors du traitement de la demande. UNEXPECTED_ERROR_DETAILS = Erreur inattendue lors du traitement de la demande.
NO_ENOUGH_PERMISSIONS=Cette carte n'est plus accessible.
NO_ENOUGH_PERMISSIONS_DETAILS=Vous n'avez pas les droits d'accès suffisants pour voir cette carte. Cette carte est devenue privée, ou a été détruite.

View File

@ -8,6 +8,13 @@
http://www.springframework.org/schema/security http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security.xsd"> http://www.springframework.org/schema/security/spring-security.xsd">
<bean id="custom-firewall" class="org.springframework.security.web.firewall.StrictHttpFirewall">
<property name="allowSemicolon" value="true"/>
</bean>
<sec:http-firewall ref="custom-firewall"/>
<sec:http pattern="/static/webapp/**" security="none"/> <sec:http pattern="/static/webapp/**" security="none"/>
<sec:http pattern="/static/mindplot/**" security="none"/> <sec:http pattern="/static/mindplot/**" security="none"/>
<sec:http pattern="/c/login" security="none"/> <sec:http pattern="/c/login" security="none"/>

View File

@ -64,12 +64,6 @@
class="org.springframework.web.servlet.i18n.SessionLocaleResolver"> class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
</bean> </bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- one of the properties available; the maximum file size in bytes -->
<property name="maxUploadSize" value="522240"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames"> <property name="basenames">
<list> <list>

View File

@ -0,0 +1 @@
google.com, pub-4996113942657337, DIRECT, f08c47fec0942fa0

View File

@ -1,13 +1,16 @@
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<c:if test="${requestScope['google.analytics.enabled']}"> <c:if test="${requestScope['google.analytics.enabled']}">
<!-- Global site tag (gtag.js) - Google Analytics --> <!-- Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-2347723-1"></script> <script>
<script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
window.dataLayer = window.dataLayer || []; (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
function gtag() { dataLayer.push(arguments); } m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
gtag('js', new Date()); })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
gtag('config', );
</script> ga('create', '${requestScope['google.analytics.account']}', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
</c:if> </c:if>

View File

@ -46,7 +46,6 @@
var accountEmail = '${principal.email}'; var accountEmail = '${principal.email}';
var mapTitle = '${mindmap.title}'; var mapTitle = '${mindmap.title}';
</script> </script>
<%@ include file="/jsp/googleAnalytics.jsf" %>
</head> </head>
<body> <body>

View File

@ -1,95 +0,0 @@
<%--@elvariable id="mindmap" type="com.wisemapping.model.Mindmap"--%>
<div id="toolbar">
<div id="backToList">
<img src="../../images/editor/back-icon.svg" />
</div>
<c:if test="${!memoryPersistence}">
<div id="persist" class="buttonContainer">
<div id="save" class="buttonOn">
<img src="../../images/editor/save.svg"/>
</div>
</div>
</c:if>
<c:if test="${!readOnlyMode}">
<div id="edit" class="buttonContainer">
<div id="undoEdition" class="buttonOn">
<img src="../../images/editor/undo.svg"/>
</div>
<div id="redoEdition" class="buttonOn">
<img src="../../images/editor/redo.svg"/>
</div>
</div>
<div id="nodeStyle" class="buttonContainer">
<div id="addTopic" class="buttonOn">
<img src="../../images/editor/topic-add.svg"/>
</div>
<div id="deleteTopic" class="buttonOn">
<img src="../../images/editor/topic-delete.svg"/>
</div>
<div id="topicBorder" class="buttonExtOn">
<img src="../../images/editor/topic-border.svg"/>
</div>
<div id="topicColor" class="buttonExtOn">
<img src="../../images/editor/topic-color.svg"/>
</div>
<div id="topicShape" class="buttonExtOn">
<img src="../../images/editor/topic-shape.svg"/>
</div>
</div>
<div id="font" class="buttonContainer">
<div id="fontFamily" class="buttonOn">
<img src="../../images/editor/font-type.svg"/>
</div>
<div id="fontSize" class="buttonExtOn">
<img src="../../images/editor/font-size.svg"/>
</div>
<div id="fontBold" class="buttonOn">
<img src="../../images/editor/font-bold.svg"/>
</div>
<div id="fontItalic" class="buttonOn">
<img src="../../images/editor/font-italic.svg"/>
</div>
<div id="fontColor" class="buttonExtOn">
<img src="../../images/editor/font-color.svg"/>
</div>
</div>
<div id="nodeContent" class="buttonContainer">
<div id="topicIcon" class="buttonExtOn">
<img src="../../images/editor/topic-icon.svg"/>
</div>
<div id="topicNote" class="buttonOn" >
<img src="../../images/editor/topic-note.svg"/>
</div>
<div id="topicLink" class="buttonOn">
<img src="../../images/editor/topic-link.svg"/>
</div>
<div id="topicRelation" class="buttonOn">
<img src="../../images/editor/topic-relation.svg"/>
</div>
</div>
<div id="separator" class="buttonContainer"></div>
</c:if>
<c:if test="${!memoryPersistence}">
<div id="toolbarRight">
<div id="export" class="buttonOn">
<img src="../../images/editor/export.svg" />
</div>
<div id="publishIt" class="buttonOn">
<img src="../../images/editor/public.svg" />
</div>
<div id="history" class="buttonOn">
<img src="../../images/editor/history.svg" />
</div>
<div id="print" class="buttonOn">
<img src="../../images/editor/print.svg" />
</div>
<div id="account">
<img src="../../images/editor/account.svg"/>
</div>
<div id="share" class="actionButton">
<spring:message code="SHARE"/>
</div>
</div>
</c:if>
</div>

View File

@ -52,8 +52,9 @@
</div> </div>
</div> </div>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
// Hock zoom events ... // Hook zoom events ...
const zoomInButton = document.getElementById('zoom-plus'); const zoomInButton = document.getElementById('zoom-plus');
if (zoomInButton) { if (zoomInButton) {
zoomInButton.addEventListener('click', () => { zoomInButton.addEventListener('click', () => {

View File

@ -23,8 +23,6 @@
}; };
</script> </script>
<%@ include file="/jsp/googleAnalytics.jsf" %>
<c:if test="${requestScope['google.analytics.enabled']}"> <c:if test="${requestScope['google.analytics.enabled']}">
<!-- Google Ads Sense Config--> <!-- Google Ads Sense Config-->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4996113942657337" crossorigin="anonymous"></script> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-4996113942657337" crossorigin="anonymous"></script>