mirror of
https://bitbucket.org/wisemapping/wisemapping-open-source.git
synced 2024-11-22 06:07:57 +01:00
Add reCaptcha as default implementation
Add support for enabling and disabling captcha
This commit is contained in:
parent
f82f024fb7
commit
773d164256
2
.gitignore
vendored
2
.gitignore
vendored
@ -4,7 +4,7 @@ wisemapping.ipr
|
|||||||
wisemapping.iws
|
wisemapping.iws
|
||||||
wisemapping.iml
|
wisemapping.iml
|
||||||
wisemapping.ids
|
wisemapping.ids
|
||||||
wise-webapp/wisemapping.log*
|
*/wisemapping.log*
|
||||||
*/.DS_Store
|
*/.DS_Store
|
||||||
.DS_Store
|
.DS_Store
|
||||||
target
|
target
|
||||||
|
@ -193,12 +193,6 @@
|
|||||||
<version>1.0.1B</version>
|
<version>1.0.1B</version>
|
||||||
<scope>runtime</scope>
|
<scope>runtime</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.octo.captcha</groupId>
|
|
||||||
<artifactId>jcaptcha</artifactId>
|
|
||||||
<version>1.0</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework</groupId>
|
<groupId>org.springframework</groupId>
|
||||||
<artifactId>spring-jdbc</artifactId>
|
<artifactId>spring-jdbc</artifactId>
|
||||||
@ -308,6 +302,17 @@
|
|||||||
<version>2.10.0</version>
|
<version>2.10.0</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.tanesha.recaptcha4j</groupId>
|
||||||
|
<artifactId>recaptcha4j</artifactId>
|
||||||
|
<version>0.0.7</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>1.2</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -1,93 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2011] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.wisemapping.controller;
|
|
||||||
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
|
|
||||||
import javax.servlet.ServletOutputStream;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
import org.springframework.web.servlet.mvc.Controller;
|
|
||||||
|
|
||||||
import com.octo.captcha.service.image.ImageCaptchaService;
|
|
||||||
|
|
||||||
import com.sun.image.codec.jpeg.JPEGCodec;
|
|
||||||
import com.sun.image.codec.jpeg.JPEGImageEncoder;
|
|
||||||
|
|
||||||
public class CaptchaController
|
|
||||||
implements Controller, InitializingBean
|
|
||||||
{
|
|
||||||
private ImageCaptchaService captchaService;
|
|
||||||
|
|
||||||
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
|
|
||||||
byte[] captchaChallengeAsJpeg;
|
|
||||||
// the output stream to render the captcha image as jpeg into
|
|
||||||
final ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
// get the session id that will identify the generated captcha.
|
|
||||||
//the same id must be used to validate the response, the session id is a good candidate!
|
|
||||||
final String captchaId = request.getSession().getId();
|
|
||||||
|
|
||||||
// call the ImageCaptchaService getChallenge method
|
|
||||||
final BufferedImage challenge = captchaService.getImageChallengeForID(captchaId,request.getLocale());
|
|
||||||
|
|
||||||
// a jpeg encoder
|
|
||||||
final JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream);
|
|
||||||
jpegEncoder.encode(challenge);
|
|
||||||
|
|
||||||
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
|
|
||||||
|
|
||||||
// flush it in the response
|
|
||||||
response.setHeader("Cache-Control", "no-store");
|
|
||||||
response.setHeader("Pragma", "no-cache");
|
|
||||||
response.setDateHeader("Expires", 0);
|
|
||||||
response.setContentType("image/jpeg");
|
|
||||||
final ServletOutputStream responseOutputStream = response.getOutputStream();
|
|
||||||
responseOutputStream.write(captchaChallengeAsJpeg);
|
|
||||||
responseOutputStream.flush();
|
|
||||||
responseOutputStream.close();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Set captcha service
|
|
||||||
* @param captchaService The captchaService to set.
|
|
||||||
*/
|
|
||||||
public void setCaptchaService(ImageCaptchaService captchaService) {
|
|
||||||
this.captchaService = captchaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
|
||||||
*/
|
|
||||||
public void afterPropertiesSet()
|
|
||||||
throws Exception
|
|
||||||
{
|
|
||||||
if(captchaService == null){
|
|
||||||
throw new RuntimeException("captcha service wasn`t set!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,109 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2011] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.wisemapping.controller;
|
|
||||||
|
|
||||||
import com.octo.captcha.service.CaptchaServiceException;
|
|
||||||
import com.octo.captcha.service.image.ImageCaptchaService;
|
|
||||||
import org.springframework.validation.BindException;
|
|
||||||
import org.springframework.web.servlet.mvc.SimpleFormController;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convenient superclass for form controller implementations which need
|
|
||||||
* CAPTCHA support.
|
|
||||||
*/
|
|
||||||
public class CaptchaFormController extends SimpleFormController {
|
|
||||||
/**
|
|
||||||
* Default paramter name for CAPTCHA response in <code>{@link HttpServletRequest}</code>
|
|
||||||
*/
|
|
||||||
private static final String DEFAULT_CAPTCHA_RESPONSE_PARAMETER_NAME = "j_captcha_response";
|
|
||||||
|
|
||||||
protected ImageCaptchaService captchaService;
|
|
||||||
protected String captchaResponseParameterName = DEFAULT_CAPTCHA_RESPONSE_PARAMETER_NAME;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delegates request to CAPTCHA validation, subclasses which overrides this
|
|
||||||
* method must manually call <code>{@link #validateCaptcha(HttpServletRequest,BindException)}</code>
|
|
||||||
* or explicitly call super method.
|
|
||||||
*
|
|
||||||
* @see #validateCaptcha(HttpServletRequest,BindException)
|
|
||||||
* @see org.springframework.web.servlet.mvc.BaseCommandController#onBindAndValidate(javax.servlet.http.HttpServletRequest,java.lang.Object,org.springframework.validation.BindException)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) throws Exception {
|
|
||||||
validateCaptcha(request, errors);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate CAPTCHA response, if response isn`t valid creates new error object
|
|
||||||
* and put him to errors holder.
|
|
||||||
*
|
|
||||||
* @param request current servlet request
|
|
||||||
* @param errors errors holder
|
|
||||||
*/
|
|
||||||
protected void validateCaptcha(HttpServletRequest request, BindException errors) {
|
|
||||||
boolean isResponseCorrect = false;
|
|
||||||
|
|
||||||
//remenber that we need an id to validate!
|
|
||||||
String captchaId = request.getSession().getId();
|
|
||||||
//retrieve the response
|
|
||||||
String response = request.getParameter(captchaResponseParameterName);
|
|
||||||
//validate response
|
|
||||||
try {
|
|
||||||
if (response != null) {
|
|
||||||
isResponseCorrect =
|
|
||||||
captchaService.validateResponseForID(captchaId, response);
|
|
||||||
}
|
|
||||||
} catch (CaptchaServiceException e) {
|
|
||||||
//should not happen, may be thrown if the id is not valid
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isResponseCorrect) {
|
|
||||||
//prepare object error, captcha response isn`t valid
|
|
||||||
// String objectName = "Captcha";
|
|
||||||
// String[] codes = {"invalid"};
|
|
||||||
// Object[] arguments = {};
|
|
||||||
// String defaultMessage = "Wrong control text!";
|
|
||||||
// ObjectError oe = new ObjectError(objectName, codes, arguments, defaultMessage);
|
|
||||||
//
|
|
||||||
// errors.addError(oe);
|
|
||||||
errors.rejectValue("captcha", Messages.CAPTCHA_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set captcha service
|
|
||||||
*
|
|
||||||
* @param captchaService the captchaService to set.
|
|
||||||
*/
|
|
||||||
public void setCaptchaService(ImageCaptchaService captchaService) {
|
|
||||||
this.captchaService = captchaService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set paramter name for CAPTCHA response in <code>{@link HttpServletRequest}</code>
|
|
||||||
*
|
|
||||||
* @param captchaResponseParameterName the captchaResponseParameterName to set.
|
|
||||||
*/
|
|
||||||
public void setCaptchaResponseParameterName(String captchaResponseParameterName) {
|
|
||||||
this.captchaResponseParameterName = captchaResponseParameterName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright [2011] [wisemapping]
|
|
||||||
*
|
|
||||||
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
|
||||||
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
|
||||||
* "powered by wisemapping" text requirement on every single page;
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the license at
|
|
||||||
*
|
|
||||||
* http://www.wisemapping.org/license
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.wisemapping.controller;
|
|
||||||
|
|
||||||
import com.wisemapping.model.User;
|
|
||||||
import com.wisemapping.service.UserService;
|
|
||||||
import com.wisemapping.view.UserBean;
|
|
||||||
import com.wisemapping.exceptions.WiseMappingException;
|
|
||||||
import org.springframework.web.servlet.ModelAndView;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class UserController
|
|
||||||
extends CaptchaFormController {
|
|
||||||
|
|
||||||
//~ Instance fields ......................................................................................
|
|
||||||
|
|
||||||
private boolean emailConfirmEnabled;
|
|
||||||
private UserService userService;
|
|
||||||
|
|
||||||
//~ Methods ..............................................................................................
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isEmailConfirmEnabled() {
|
|
||||||
return emailConfirmEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEmailConfirmEnabled(boolean emailConfirmEnabled) {
|
|
||||||
this.emailConfirmEnabled = emailConfirmEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModelAndView onSubmit(Object command) throws WiseMappingException {
|
|
||||||
final UserBean userBean = ((UserBean) command);
|
|
||||||
|
|
||||||
if (userBean != null) {
|
|
||||||
final User user = new User();
|
|
||||||
// trim() the email email in order to remove spaces
|
|
||||||
user.setEmail(userBean.getEmail().trim());
|
|
||||||
user.setUsername(userBean.getUsername());
|
|
||||||
user.setFirstname(userBean.getFirstname());
|
|
||||||
user.setLastname(userBean.getLastname());
|
|
||||||
user.setPassword(userBean.getPassword());
|
|
||||||
userService.createUser(user,emailConfirmEnabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
final Map<String,Object> model = new HashMap<String,Object>();
|
|
||||||
model.put("confirmByEmail",emailConfirmEnabled);
|
|
||||||
return new ModelAndView(getSuccessView(),model);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserService(UserService userService) {
|
|
||||||
this.userService = userService;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright [2011] [wisemapping]
|
||||||
|
*
|
||||||
|
* Licensed under WiseMapping Public License, Version 1.0 (the "License").
|
||||||
|
* It is basically the Apache License, Version 2.0 (the "License") plus the
|
||||||
|
* "powered by wisemapping" text requirement on every single page;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the license at
|
||||||
|
*
|
||||||
|
* http://www.wisemapping.org/license
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wisemapping.controller;
|
||||||
|
|
||||||
|
import com.wisemapping.model.User;
|
||||||
|
import com.wisemapping.service.UserService;
|
||||||
|
import com.wisemapping.view.UserBean;
|
||||||
|
import com.wisemapping.exceptions.WiseMappingException;
|
||||||
|
import net.tanesha.recaptcha.ReCaptcha;
|
||||||
|
import net.tanesha.recaptcha.ReCaptchaResponse;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.validation.ObjectError;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class UserRegistrationController
|
||||||
|
extends BaseSimpleFormController {
|
||||||
|
|
||||||
|
//~ Instance fields ......................................................................................
|
||||||
|
|
||||||
|
private boolean emailConfirmEnabled;
|
||||||
|
private UserService userService;
|
||||||
|
private ReCaptcha captchaService;
|
||||||
|
private boolean captchaEnabled;
|
||||||
|
|
||||||
|
//~ Methods ..............................................................................................
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isEmailConfirmEnabled() {
|
||||||
|
return emailConfirmEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmailConfirmEnabled(boolean emailConfirmEnabled) {
|
||||||
|
this.emailConfirmEnabled = emailConfirmEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelAndView onSubmit(@Nullable Object command) throws WiseMappingException {
|
||||||
|
final UserBean userBean = ((UserBean) command);
|
||||||
|
|
||||||
|
if (userBean != null) {
|
||||||
|
final User user = new User();
|
||||||
|
// trim() the email email in order to remove spaces
|
||||||
|
user.setEmail(userBean.getEmail().trim());
|
||||||
|
user.setUsername(userBean.getUsername());
|
||||||
|
user.setFirstname(userBean.getFirstname());
|
||||||
|
user.setLastname(userBean.getLastname());
|
||||||
|
user.setPassword(userBean.getPassword());
|
||||||
|
userService.createUser(user, emailConfirmEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Object> model = new HashMap<String, Object>();
|
||||||
|
model.put("confirmByEmail", emailConfirmEnabled);
|
||||||
|
return new ModelAndView(getSuccessView(), model);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserService(UserService userService) {
|
||||||
|
this.userService = userService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCaptchaService(@NotNull final ReCaptcha captchaService) {
|
||||||
|
this.captchaService = captchaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReCaptcha getCaptchaService() {
|
||||||
|
return captchaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCaptchaEnabled() {
|
||||||
|
return captchaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCaptchaEnabled(boolean captchaEnabled) {
|
||||||
|
this.captchaEnabled = captchaEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onBindAndValidate(HttpServletRequest request, Object command, BindException errors) throws Exception {
|
||||||
|
|
||||||
|
super.onBindAndValidate(request, command, errors);
|
||||||
|
// If captcha is enabled, generate it ...
|
||||||
|
if (isCaptchaEnabled()) {
|
||||||
|
|
||||||
|
final String challenge = request.getParameter("recaptcha_challenge_field");
|
||||||
|
final String uresponse = request.getParameter("recaptcha_response_field");
|
||||||
|
|
||||||
|
final String remoteAddr = request.getRemoteAddr();
|
||||||
|
final ReCaptchaResponse reCaptchaResponse = captchaService.checkAnswer(remoteAddr, challenge, uresponse);
|
||||||
|
if (!reCaptchaResponse.isValid()) {
|
||||||
|
errors.rejectValue("captcha", Messages.CAPTCHA_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ModelAndView showForm(HttpServletRequest request, HttpServletResponse response, BindException bindException) throws Exception {
|
||||||
|
final ModelAndView modelAndView = super.showForm(request, response, bindException);
|
||||||
|
|
||||||
|
// If captcha is enabled, generate it ...
|
||||||
|
if (isCaptchaEnabled()) {
|
||||||
|
final Properties prop = new Properties();
|
||||||
|
prop.put("theme", "white");
|
||||||
|
final String captchaHtml = captchaService.createRecaptchaHtml(null, prop);
|
||||||
|
request.setAttribute("captchaHtml", captchaHtml);
|
||||||
|
request.setAttribute("captchaEnabled", true);
|
||||||
|
}
|
||||||
|
return modelAndView;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -107,12 +107,12 @@ public class User
|
|||||||
|
|
||||||
final User user = (User) o;
|
final User user = (User) o;
|
||||||
|
|
||||||
if (!getEmail().equals(user.getEmail())) return false;
|
final String email = getEmail();
|
||||||
|
if (email != null ? !email.equals(user.getEmail()) : user.getEmail() != null) return false;
|
||||||
if (firstname != null ? !firstname.equals(user.firstname) : user.firstname != null) return false;
|
if (firstname != null ? !firstname.equals(user.firstname) : user.firstname != null) return false;
|
||||||
if (lastname != null ? !lastname.equals(user.lastname) : user.lastname != null) return false;
|
if (lastname != null ? !lastname.equals(user.lastname) : user.lastname != null) return false;
|
||||||
if (username != null ? !username.equals(user.username) : user.username != null) return false;
|
return !(username != null ? !username.equals(user.username) : user.username != null);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
@ -120,7 +120,7 @@ public class User
|
|||||||
result = (firstname != null ? firstname.hashCode() : 0);
|
result = (firstname != null ? firstname.hashCode() : 0);
|
||||||
result = 29 * result + (lastname != null ? lastname.hashCode() : 0);
|
result = 29 * result + (lastname != null ? lastname.hashCode() : 0);
|
||||||
result = 29 * result + (password != null ? password.hashCode() : 0);
|
result = 29 * result + (password != null ? password.hashCode() : 0);
|
||||||
result = 29 * result + getEmail().hashCode();
|
result = 29 * result + (getEmail() != null ? getEmail().hashCode() : 0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,9 @@ import com.wisemapping.controller.Messages;
|
|||||||
import com.wisemapping.service.UserService;
|
import com.wisemapping.service.UserService;
|
||||||
import com.wisemapping.view.UserBean;
|
import com.wisemapping.view.UserBean;
|
||||||
import com.wisemapping.model.Constants;
|
import com.wisemapping.model.Constants;
|
||||||
|
import net.tanesha.recaptcha.ReCaptcha;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.ValidationUtils;
|
import org.springframework.validation.ValidationUtils;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
@ -30,12 +33,14 @@ public class UserValidator
|
|||||||
implements Validator {
|
implements Validator {
|
||||||
|
|
||||||
private UserService userService;
|
private UserService userService;
|
||||||
|
private ReCaptcha captchaService;
|
||||||
|
|
||||||
|
|
||||||
public boolean supports(final Class clazz) {
|
public boolean supports(final Class clazz) {
|
||||||
return clazz.equals(UserBean.class);
|
return clazz.equals(UserBean.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(Object obj, Errors errors) {
|
public void validate(@Nullable Object obj, @NotNull Errors errors) {
|
||||||
UserBean user = (UserBean) obj;
|
UserBean user = (UserBean) obj;
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
errors.rejectValue("user", "error.not-specified");
|
errors.rejectValue("user", "error.not-specified");
|
||||||
@ -65,30 +70,30 @@ public class UserValidator
|
|||||||
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", Messages.FIELD_REQUIRED);
|
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password", Messages.FIELD_REQUIRED);
|
||||||
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "retypePassword", Messages.FIELD_REQUIRED);
|
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "retypePassword", Messages.FIELD_REQUIRED);
|
||||||
ValidatorUtils.rejectIfExceeded(errors,
|
ValidatorUtils.rejectIfExceeded(errors,
|
||||||
"firstname",
|
"firstname",
|
||||||
"The firstname must have less than "+ Constants.MAX_USER_FIRSTNAME_LENGTH + " characters.",
|
"The firstname must have less than " + Constants.MAX_USER_FIRSTNAME_LENGTH + " characters.",
|
||||||
user.getFirstname(),
|
user.getFirstname(),
|
||||||
Constants.MAX_USER_FIRSTNAME_LENGTH);
|
Constants.MAX_USER_FIRSTNAME_LENGTH);
|
||||||
ValidatorUtils.rejectIfExceeded(errors,
|
ValidatorUtils.rejectIfExceeded(errors,
|
||||||
"lastname",
|
"lastname",
|
||||||
"The lastname must have less than "+ Constants.MAX_USER_LASTNAME_LENGTH + " characters.",
|
"The lastname must have less than " + Constants.MAX_USER_LASTNAME_LENGTH + " characters.",
|
||||||
user.getLastname(),
|
user.getLastname(),
|
||||||
Constants.MAX_USER_LASTNAME_LENGTH);
|
Constants.MAX_USER_LASTNAME_LENGTH);
|
||||||
ValidatorUtils.rejectIfExceeded(errors,
|
ValidatorUtils.rejectIfExceeded(errors,
|
||||||
"username",
|
"username",
|
||||||
"The username must have less than "+ Constants.MAX_USER_USERNAME_LENGTH + " characters.",
|
"The username must have less than " + Constants.MAX_USER_USERNAME_LENGTH + " characters.",
|
||||||
username,
|
username,
|
||||||
Constants.MAX_USER_USERNAME_LENGTH);
|
Constants.MAX_USER_USERNAME_LENGTH);
|
||||||
ValidatorUtils.rejectIfExceeded(errors,
|
ValidatorUtils.rejectIfExceeded(errors,
|
||||||
"password",
|
"password",
|
||||||
"The password must have less than "+ Constants.MAX_USER_PASSWORD_LENGTH + " characters.",
|
"The password must have less than " + Constants.MAX_USER_PASSWORD_LENGTH + " characters.",
|
||||||
user.getPassword(),
|
user.getPassword(),
|
||||||
Constants.MAX_USER_PASSWORD_LENGTH);
|
Constants.MAX_USER_PASSWORD_LENGTH);
|
||||||
ValidatorUtils.rejectIfExceeded(errors,
|
ValidatorUtils.rejectIfExceeded(errors,
|
||||||
"retypePassword",
|
"retypePassword",
|
||||||
"The retypePassword must have less than "+ Constants.MAX_USER_PASSWORD_LENGTH + " characters.",
|
"The retypePassword must have less than " + Constants.MAX_USER_PASSWORD_LENGTH + " characters.",
|
||||||
user.getRetypePassword(),
|
user.getRetypePassword(),
|
||||||
Constants.MAX_USER_PASSWORD_LENGTH);
|
Constants.MAX_USER_PASSWORD_LENGTH);
|
||||||
|
|
||||||
final String password = user.getPassword();
|
final String password = user.getPassword();
|
||||||
if (password != null && !password.equals(user.getRetypePassword())) {
|
if (password != null && !password.equals(user.getRetypePassword())) {
|
||||||
@ -100,4 +105,12 @@ public class UserValidator
|
|||||||
public void setUserService(UserService userService) {
|
public void setUserService(UserService userService) {
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setCaptchaService(@NotNull final ReCaptcha captchaService) {
|
||||||
|
this.captchaService = captchaService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReCaptcha getCaptchaService() {
|
||||||
|
return captchaService;
|
||||||
|
}
|
||||||
}
|
}
|
@ -44,6 +44,7 @@ database.password=
|
|||||||
#------------------------
|
#------------------------
|
||||||
# GMAIL SMTP Configuration
|
# GMAIL SMTP Configuration
|
||||||
#------------------------
|
#------------------------
|
||||||
|
mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
|
||||||
mail.smtp.socketFactory.port=587
|
mail.smtp.socketFactory.port=587
|
||||||
mail.smtp.auth = true
|
mail.smtp.auth = true
|
||||||
mail.host=smtp.gmail.com
|
mail.host=smtp.gmail.com
|
||||||
@ -54,19 +55,28 @@ mail.smtp.starttls.enable=true
|
|||||||
#------------------------
|
#------------------------
|
||||||
# Domain address
|
# Domain address
|
||||||
#------------------------
|
#------------------------
|
||||||
|
|
||||||
mail.registrationEmail=root@localhost
|
mail.registrationEmail=root@localhost
|
||||||
mail.siteEmail=root@localhost
|
mail.siteEmail=root@localhost
|
||||||
|
|
||||||
|
##################################################################################
|
||||||
|
# Users Registration Configuration
|
||||||
|
##################################################################################
|
||||||
|
|
||||||
|
# Enable/Disable user registration confirmation by e-mail. If it's enabled, mail must be configured.
|
||||||
|
registration.email.enabled = false
|
||||||
|
|
||||||
|
# Enable captcha confirmation
|
||||||
|
registration.recaptcha.enabled = false
|
||||||
|
|
||||||
|
# ReCaptcha is the default captcha. Public and private keys are required.
|
||||||
|
# More Info: http://www.google.com/recaptcha
|
||||||
|
registration.recaptcha.privateKey =
|
||||||
|
registration.recaptcha.publicKey =
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
# Site configuration
|
# Site configuration
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
|
||||||
# Enable/Disable user registration confirmation by e-mail. If it's enabled, mail must be configured.
|
|
||||||
user.confirm.registration=false
|
|
||||||
|
|
||||||
# Site administration user. This user will have special permissions for operations such as removing users, set password
|
# Site administration user. This user will have special permissions for operations such as removing users, set password
|
||||||
# etc.
|
# etc.
|
||||||
admin.user = admin@wisemapping.org
|
admin.user = admin@wisemapping.org
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
log4j.rootLogger=WARN, stdout, R
|
log4j.rootLogger=WARN, stdout, R
|
||||||
log4j.logger.com.wisemapping=WARN,stdout,R
|
log4j.logger.com.wisemapping=WARN,stdout,R
|
||||||
log4j.logger.org.springframework=DEBUG,stdout,R
|
log4j.logger.org.springframework=WARN,stdout,R
|
||||||
log4j.logger.org.codehaus.jackson=WARN,stdout,R
|
log4j.logger.org.codehaus.jackson=WARN,stdout,R
|
||||||
|
|
||||||
# Stdout logger <20>
|
# Stdout logger <20>
|
||||||
|
@ -116,10 +116,10 @@
|
|||||||
|
|
||||||
<bean id="userValidator" class="com.wisemapping.validator.UserValidator">
|
<bean id="userValidator" class="com.wisemapping.validator.UserValidator">
|
||||||
<property name="userService" ref="userService"/>
|
<property name="userService" ref="userService"/>
|
||||||
|
<property name="captchaService" ref="reCaptcha"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="userController" class="com.wisemapping.controller.UserController">
|
<bean id="userController" class="com.wisemapping.controller.UserRegistrationController">
|
||||||
<!--<property name="captchaService" ref="captchaService"/>-->
|
|
||||||
<property name="sessionForm" value="false"/>
|
<property name="sessionForm" value="false"/>
|
||||||
<property name="commandName" value="user"/>
|
<property name="commandName" value="user"/>
|
||||||
<property name="commandClass" value="com.wisemapping.view.UserBean"/>
|
<property name="commandClass" value="com.wisemapping.view.UserBean"/>
|
||||||
@ -127,7 +127,9 @@
|
|||||||
<property name="formView" value="userRegistration"/>
|
<property name="formView" value="userRegistration"/>
|
||||||
<property name="successView" value="userRegistrationConfirmation"/>
|
<property name="successView" value="userRegistrationConfirmation"/>
|
||||||
<property name="userService" ref="userService"/>
|
<property name="userService" ref="userService"/>
|
||||||
<property name="emailConfirmEnabled" value="${user.confirm.registration}"/>
|
<property name="emailConfirmEnabled" value="${registration.email.enabled}"/>
|
||||||
|
<property name="captchaEnabled" value="${registration.recaptcha.enabled}"/>
|
||||||
|
<property name="captchaService" ref="reCaptcha"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<bean id="forgotPasswordValidator" class="com.wisemapping.validator.ForgotPasswordValidator"/>
|
<bean id="forgotPasswordValidator" class="com.wisemapping.validator.ForgotPasswordValidator"/>
|
||||||
@ -275,10 +277,6 @@
|
|||||||
<property name="mindmapService" ref="mindmapService"/>
|
<property name="mindmapService" ref="mindmapService"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!--<bean id="captchaController" class="com.wisemapping.controller.CaptchaController">-->
|
|
||||||
<!--<property name="captchaService" ref="captchaService"/>-->
|
|
||||||
<!--</bean>-->
|
|
||||||
|
|
||||||
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
|
||||||
<property name="interceptors">
|
<property name="interceptors">
|
||||||
<list>
|
<list>
|
||||||
@ -337,5 +335,9 @@
|
|||||||
<property name="paramName" value="language"/>
|
<property name="paramName" value="language"/>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="reCaptcha" class="net.tanesha.recaptcha.ReCaptchaImpl">
|
||||||
|
<property name="privateKey" value="${registration.recaptcha.privateKey}"/>
|
||||||
|
<property name="publicKey" value="${registration.recaptcha.publicKey}"/>
|
||||||
|
<property name="includeNoscript" value="false"/>
|
||||||
|
</bean>
|
||||||
</beans>
|
</beans>
|
@ -48,8 +48,7 @@
|
|||||||
</c:if>
|
</c:if>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="formLabel">
|
<td class="formLabel">
|
||||||
<spring:message code="EMAIL"/>
|
<spring:message code="EMAIL"/>:
|
||||||
:
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type='text' tabindex="1" id="email" name='j_username'/>
|
<input type='text' tabindex="1" id="email" name='j_username'/>
|
||||||
@ -57,8 +56,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="formLabel">
|
<td class="formLabel">
|
||||||
<spring:message code="PASSWORD"/>
|
<spring:message code="PASSWORD"/>:
|
||||||
:
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input type='password' tabindex="2" id="password" name='j_password'/>
|
<input type='password' tabindex="2" id="password" name='j_password'/>
|
||||||
|
@ -1,19 +1,6 @@
|
|||||||
<%@ include file="/jsp/init.jsp" %>
|
<%@ include file="/jsp/init.jsp" %>
|
||||||
<%--@elvariable id="wisemapDetail" type="com.wisemapping.view.MindMapBean"--%>
|
<%--@elvariable id="wisemapDetail" type="com.wisemapping.view.MindMapBean"--%>
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
if(typeof isOldIE != "undefined"){
|
|
||||||
window.onload = function() {
|
|
||||||
var boxGenerator = RUZEE.ShadedBorder.create({ corner:16, border:1 });
|
|
||||||
boxGenerator.render('detailContent');
|
|
||||||
boxGenerator.render('detail');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
MOOdalBox.reloadRequered = true;
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<c:url value="mymaps.htm" var="shareMap">
|
<c:url value="mymaps.htm" var="shareMap">
|
||||||
<c:param name="action" value="collaborator"/>
|
<c:param name="action" value="collaborator"/>
|
||||||
<c:param name="userEmail" value="${pageContext.request.userPrincipal.name}"/>
|
<c:param name="userEmail" value="${pageContext.request.userPrincipal.name}"/>
|
||||||
|
@ -1,139 +1,117 @@
|
|||||||
<%@ include file="/jsp/init.jsp" %>
|
<%@ include file="/jsp/init.jsp" %>
|
||||||
|
|
||||||
<script type="text/javascript">
|
|
||||||
if(typeof isOldIE != "undefined"){
|
|
||||||
window.onload = function() {
|
|
||||||
var simpleButtonGenerator = RUZEE.ShadedBorder.create({ corner:8, border:1 });
|
|
||||||
simpleButtonGenerator.render('userRegistration');
|
|
||||||
|
|
||||||
$('submitButton').addEvent('click', displayLoading);
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div id="userRegistrationContent">
|
<div id="userRegistrationContent">
|
||||||
<div id="userRegistration" class="sb">
|
<div id="userRegistration">
|
||||||
<h1>
|
<h1>
|
||||||
<spring:message code="USER_REGISTRATION"/>
|
<spring:message code="USER_REGISTRATION"/>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
<spring:message code="REGISTRATION_TITLE_MSG"/>
|
<spring:message code="REGISTRATION_TITLE_MSG"/>
|
||||||
<br/><br/>
|
<br/><br/>
|
||||||
<spring:message code="FIELD_REQUIRED_MSG"/>
|
<spring:message code="FIELD_REQUIRED_MSG"/>
|
||||||
</h2>
|
</h2>
|
||||||
<form:form method="post" commandName="user">
|
<form:form method="post" commandName="user">
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="formLabel">
|
<td class="formLabel">
|
||||||
<span class="fieldRequired">*</span>
|
<span class="fieldRequired">*</span>
|
||||||
<spring:message code="EMAIL"/>
|
<spring:message code="EMAIL"/>:
|
||||||
:
|
</td>
|
||||||
</td>
|
<td>
|
||||||
<td>
|
<form:input path="email" id="email"/>
|
||||||
<form:input path="email" id="email"/>
|
<form:errors path="email" cssClass="errorMsg"/>
|
||||||
<form:errors path="email" cssClass="errorMsg"/>
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
</tr>
|
<tr>
|
||||||
<tr>
|
<td class="formLabel">
|
||||||
<td class="formLabel">
|
<span class="fieldRequired">*</span>
|
||||||
<span class="fieldRequired">*</span>
|
<spring:message code="USERNAME"/>:
|
||||||
<spring:message code="USERNAME"/>
|
</td>
|
||||||
:
|
<td>
|
||||||
</td>
|
<form:input path="username" id="username"/>
|
||||||
<td>
|
<form:errors path="username" cssClass="errorMsg"/>
|
||||||
<form:input path="username" id="username"/>
|
</td>
|
||||||
<form:errors path="username" cssClass="errorMsg"/>
|
</tr>
|
||||||
</td>
|
<tr>
|
||||||
</tr>
|
<td class="formLabel">
|
||||||
<tr>
|
<span class="fieldRequired">*</span>
|
||||||
<td class="formLabel">
|
<spring:message code="FIRSTNAME"/>:
|
||||||
<span class="fieldRequired">*</span>
|
</td>
|
||||||
<spring:message code="FIRSTNAME"/>
|
<td>
|
||||||
:
|
<form:input path="firstname" id="firstname"/>
|
||||||
</td>
|
<form:errors path="firstname" cssClass="errorMsg"/>
|
||||||
<td>
|
</td>
|
||||||
<form:input path="firstname" id="firstname"/>
|
</tr>
|
||||||
<form:errors path="firstname" cssClass="errorMsg"/>
|
<tr>
|
||||||
</td>
|
<td class="formLabel">
|
||||||
</tr>
|
<span class="fieldRequired">*</span>
|
||||||
<tr>
|
<spring:message code="LASTNAME"/>:
|
||||||
<td class="formLabel">
|
</td>
|
||||||
<span class="fieldRequired">*</span>
|
<td>
|
||||||
<spring:message code="LASTNAME"/>
|
<form:input path="lastname" id="lastname"/>
|
||||||
:
|
<form:errors path="lastname" cssClass="errorMsg"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
<form:input path="lastname" id="lastname"/>
|
<tr>
|
||||||
<form:errors path="lastname" cssClass="errorMsg"/>
|
<td class="formLabel">
|
||||||
</td>
|
<span class="fieldRequired">*</span>
|
||||||
</tr>
|
<spring:message code="PASSWORD"/>:
|
||||||
<tr>
|
</td>
|
||||||
<td class="formLabel">
|
<td>
|
||||||
<span class="fieldRequired">*</span>
|
<form:password path="password" id="password"/>
|
||||||
<spring:message code="PASSWORD"/>
|
<form:errors path="password" cssClass="errorMsg"/>
|
||||||
:
|
</td>
|
||||||
</td>
|
</tr>
|
||||||
<td>
|
<tr>
|
||||||
<form:password path="password" id="password"/>
|
<td class="formLabel">
|
||||||
<form:errors path="password" cssClass="errorMsg"/>
|
<span class="fieldRequired">*</span>
|
||||||
</td>
|
<spring:message code="RETYPE_PASSWORD"/>:
|
||||||
</tr>
|
</td>
|
||||||
<tr>
|
<td>
|
||||||
<td class="formLabel">
|
<form:password path="retypePassword" id="retypePassword"/>
|
||||||
<span class="fieldRequired">*</span>
|
<form:errors path="retypePassword" cssClass="errorMsg"/>
|
||||||
<spring:message code="RETYPE_PASSWORD"/>
|
</td>
|
||||||
:
|
</tr>
|
||||||
</td>
|
<c:if test="${requestScope.captchaEnabled}">
|
||||||
<td>
|
<tr>
|
||||||
<form:password path="retypePassword" id="retypePassword"/>
|
<td class="formLabel">
|
||||||
<form:errors path="retypePassword" cssClass="errorMsg"/>
|
</td>
|
||||||
</td>
|
<td>
|
||||||
</tr>
|
<form:errors path="captcha" cssClass="errorMsg"/>
|
||||||
<tr>
|
${requestScope.captchaHtml}
|
||||||
<td class="formLabel">
|
</td>
|
||||||
<span class="fieldRequired">*</span>
|
</tr>
|
||||||
<spring:message code="WORD_VERIFICATION"/>
|
</c:if>
|
||||||
:
|
<tr>
|
||||||
</td>
|
<td class="formLabel">
|
||||||
<td>
|
<spring:message code="TERM_OF_THE_SERVICE"/>
|
||||||
<p>
|
</td>
|
||||||
<spring:message code="TYPE_CHARACTER_BELOW"/>
|
<td>
|
||||||
</p>
|
<spring:message code="WISEMAPPING_ACCOUNT_MESSAGE"/>
|
||||||
<img src="captcha.htm"/><br/>
|
<a href="termsOfUse.htm">
|
||||||
<input type="text" name="j_captcha_response"/><br/>
|
<spring:message code="HERE"/>
|
||||||
<form:errors path="captcha" cssClass="errorMsg"/>
|
</a>.<br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="formLabel">
|
<td class="formLabel"> </td>
|
||||||
<spring:message code="TERM_OF_THE_SERVICE"/>
|
<td>
|
||||||
:
|
<spring:message code="REGISTRATION_CLICK_ADVICE"/>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
</tr>
|
||||||
<spring:message code="WISEMAPPING_ACCOUNT_MESSAGE"/>
|
<tr>
|
||||||
<a href="termsOfUse.htm">
|
<td> </td>
|
||||||
<spring:message code="HERE"/>
|
<td><input type="submit" value="<spring:message code="REGISTER"/>" id="submitButton"
|
||||||
</a>.<br/>
|
class="btn-primary">
|
||||||
</td>
|
<input type="button" value="<spring:message code="CANCEL"/>"
|
||||||
</tr>
|
onclick="window.location='<c:url value="mymaps.htm"/>'" class="btn-secondary">
|
||||||
<tr>
|
</td>
|
||||||
<td class="formLabel"> </td>
|
</tr>
|
||||||
<td>
|
</tbody>
|
||||||
<spring:message code="REGISTRATION_CLICK_ADVICE"/>
|
</table>
|
||||||
</td>
|
</form:form>
|
||||||
</tr>
|
</div>
|
||||||
<tr>
|
|
||||||
<td> </td>
|
|
||||||
<td><input type="submit" value="<spring:message code="REGISTER"/>" id="submitButton" class="btn-primary">
|
|
||||||
<input type="button" value="<spring:message code="CANCEL"/>"
|
|
||||||
onclick="window.location='<c:url value="mymaps.htm"/>'" class="btn-secondary">
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</form:form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user