Compare commits
6 Commits
96b6ff3841
...
885de4e1c1
Author | SHA1 | Date |
---|---|---|
Paulo Gustavo Veiga | 885de4e1c1 | |
Paulo Gustavo Veiga | 56c322fd3f | |
Paulo Gustavo Veiga | e3998ef3d4 | |
Paulo Gustavo Veiga | 88d5f0df43 | |
Paulo Gustavo Veiga | 37d7a9bb6d | |
Paulo Gustavo Veiga | d798358fec |
|
@ -12,6 +12,5 @@ import org.springframework.context.annotation.ImportResource;
|
|||
@ComponentScan(basePackageClasses = {AuthenticationProvider.class, MindmapServiceImpl.class, LabelManagerImpl.class, VelocityEngineUtils.class})
|
||||
@Import({JPAConfig.class, SecurityConfig.class})
|
||||
@EnableAutoConfiguration
|
||||
@ImportResource(value = {"classpath:spring/wisemapping-mail.xml"})
|
||||
public class CommonConfig {
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class RestAppConfig {
|
|||
}))
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
|
||||
.httpBasic(withDefaults())
|
||||
// .httpBasic(withDefaults())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright [2022] [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.config.rest;
|
||||
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class ServletConfig implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {
|
||||
public void customize(ConfigurableServletWebServerFactory factory){
|
||||
factory.setPort(8081);
|
||||
}
|
||||
}
|
|
@ -124,17 +124,16 @@ public class MindmapManagerImpl
|
|||
|
||||
@Override
|
||||
public Mindmap getMindmapByTitle(final String title, final User user) {
|
||||
final Mindmap result;
|
||||
|
||||
final TypedQuery<Mindmap> query = entityManager.createQuery("from com.wisemapping.model.Mindmap wisemapping where title=:title and creator=:creator", Mindmap.class);
|
||||
query.setParameter("title", title);
|
||||
query.setParameter("creator", user);
|
||||
|
||||
List<Mindmap> mindMaps = query.getResultList();
|
||||
|
||||
Mindmap result = null;
|
||||
if (mindMaps != null && !mindMaps.isEmpty()) {
|
||||
result = mindMaps.get(0);
|
||||
} else {
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,10 @@ import org.apache.logging.log4j.LogManager;
|
|||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
@ -34,22 +36,22 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
@Override
|
||||
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
|
||||
final Optional<String> token = getJwtTokenFromRequest(request);
|
||||
|
||||
|
||||
if (token.isPresent() && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
// Extract email from token ...
|
||||
final Optional<String> email = extractEmailFromToken(token.get());
|
||||
|
||||
if (email.isPresent() && jwtTokenUtil.validateJwtToken(token.get())) {
|
||||
// Is it an existing user ?
|
||||
final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get());
|
||||
if (userDetails != null) {
|
||||
try {
|
||||
final UserDetails userDetails = userDetailsService.loadUserByUsername(email.get());
|
||||
final UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
|
||||
userDetails, null, userDetails.getAuthorities());
|
||||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||
} else {
|
||||
} catch (UsernameNotFoundException e) {
|
||||
logger.trace("User " + email.get() + " could not be found");
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +67,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
// Handle token extraction/validation errors
|
||||
logger.debug("Error extracting email from token: " + e.getMessage());
|
||||
}
|
||||
logger.trace("JWT token email:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -74,7 +77,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
final String authorizationHeader = request.getHeader("Authorization");
|
||||
if (authorizationHeader != null) {
|
||||
if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) {
|
||||
logger.trace("JWT Bearer token found");
|
||||
logger.trace("JWT Bearer token found.");
|
||||
final String token = authorizationHeader.substring(BEARER_TOKEN_PREFIX.length());
|
||||
result = Optional.of(token);
|
||||
}
|
||||
|
|
|
@ -311,13 +311,10 @@ public class Mindmap implements Serializable {
|
|||
}
|
||||
|
||||
public static String getDefaultMindmapXml(@NotNull final String title) {
|
||||
|
||||
final StringBuilder result = new StringBuilder();
|
||||
result.append("<map version=\"tango\" theme=\"prism\">");
|
||||
result.append("<topic central=\"true\" text=\"");
|
||||
result.append(escapeXmlAttribute(title));
|
||||
result.append("\"/></map>");
|
||||
return result.toString();
|
||||
return "<map version=\"tango\" theme=\"prism\">" +
|
||||
"<topic central=\"true\" text=\"" +
|
||||
escapeXmlAttribute(title) +
|
||||
"\"/></map>";
|
||||
}
|
||||
|
||||
static private String escapeXmlAttribute(String attValue) {
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.springframework.web.bind.annotation.*;
|
|||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/restful/account/")
|
||||
@RequestMapping("/api/restful/account")
|
||||
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||
public class AccountController extends BaseController {
|
||||
@Qualifier("userService")
|
||||
|
@ -54,7 +54,7 @@ public class AccountController extends BaseController {
|
|||
@Autowired
|
||||
private LabelService labelService;
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "password", consumes = {"text/plain"})
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/password", consumes = {"text/plain"})
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void changePassword(@RequestBody String password) throws PasswordTooLongException {
|
||||
if (password == null) {
|
||||
|
@ -76,7 +76,7 @@ public class AccountController extends BaseController {
|
|||
return new RestUser(user);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "firstname", consumes = {"text/plain"})
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/firstname", consumes = {"text/plain"})
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void changeFirstname(@RequestBody String firstname) {
|
||||
if (firstname == null) {
|
||||
|
@ -88,7 +88,7 @@ public class AccountController extends BaseController {
|
|||
userService.updateUser(user);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "lastname", consumes = {"text/plain"})
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/lastname", consumes = {"text/plain"})
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void changeLastName(@RequestBody String lastname) {
|
||||
if (lastname == null) {
|
||||
|
@ -100,7 +100,7 @@ public class AccountController extends BaseController {
|
|||
userService.updateUser(user);
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "locale", consumes = {"text/plain"})
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/locale", consumes = {"text/plain"})
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
public void changeLanguage(@RequestBody String language) {
|
||||
if (language == null) {
|
||||
|
|
|
@ -69,7 +69,7 @@ public class MindmapController extends BaseController {
|
|||
|
||||
|
||||
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"})
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{id}", produces = {"application/json"})
|
||||
@ResponseBody
|
||||
public RestMindmap retrieve(@PathVariable int id) throws WiseMappingException {
|
||||
final User user = Utils.getUser();
|
||||
|
@ -77,6 +77,16 @@ public class MindmapController extends BaseController {
|
|||
return new RestMindmap(mindMap, user);
|
||||
}
|
||||
|
||||
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/{id}/metadata", produces = {"application/json"})
|
||||
@ResponseBody
|
||||
public RestMindmap retrieveMetadata(@PathVariable int id) throws WiseMappingException {
|
||||
final User user = Utils.getUser();
|
||||
|
||||
final Mindmap mindMap = findMindmapById(id);
|
||||
return new RestMindmap(mindMap, user);
|
||||
}
|
||||
|
||||
@PreAuthorize("isAuthenticated() and hasRole('ROLE_USER')")
|
||||
@RequestMapping(method = RequestMethod.GET, value = "/", produces = {"application/json"})
|
||||
public RestMindmapList retrieveList(@RequestParam(required = false) String q) {
|
||||
|
|
|
@ -49,103 +49,104 @@ import java.util.List;
|
|||
|
||||
@RestController
|
||||
@RequestMapping("/api/restful/users")
|
||||
@CrossOrigin
|
||||
public class UserController extends BaseController {
|
||||
|
||||
@Qualifier("userService")
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
@Qualifier("userService")
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private RecaptchaService captchaService;
|
||||
@Autowired
|
||||
private RecaptchaService captchaService;
|
||||
|
||||
@Qualifier("authenticationManager")
|
||||
@Autowired
|
||||
private AuthenticationManager authManager;
|
||||
@Qualifier("authenticationManager")
|
||||
@Autowired
|
||||
private AuthenticationManager authManager;
|
||||
|
||||
@Value("${google.recaptcha2.enabled:false}")
|
||||
private Boolean recatchaEnabled;
|
||||
@Value("${google.recaptcha2.enabled:false}")
|
||||
private Boolean recatchaEnabled;
|
||||
|
||||
@Value("${accounts.exclusion.domain:''}")
|
||||
private String domainBanExclusion;
|
||||
@Value("${app.accounts.exclusion.domain:''}")
|
||||
private String domainBanExclusion;
|
||||
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP";
|
||||
private static final Logger logger = LogManager.getLogger();
|
||||
private static final String REAL_IP_ADDRESS_HEADER = "X-Real-IP";
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/", produces = { "application/json" })
|
||||
@ResponseStatus(value = HttpStatus.CREATED)
|
||||
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request,
|
||||
@NotNull HttpServletResponse response) throws WiseMappingException, BindException {
|
||||
logger.debug("Register new user:" + registration.getEmail());
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/", produces = {"application/json"})
|
||||
@ResponseStatus(value = HttpStatus.CREATED)
|
||||
public void registerUser(@RequestBody RestUserRegistration registration, @NotNull HttpServletRequest request,
|
||||
@NotNull HttpServletResponse response) throws WiseMappingException, BindException {
|
||||
logger.debug("Register new user:" + registration.getEmail());
|
||||
|
||||
if (registration.getPassword().length() > User.MAX_PASSWORD_LENGTH_SIZE) {
|
||||
throw new PasswordTooLongException();
|
||||
}
|
||||
if (registration.getPassword().length() > User.MAX_PASSWORD_LENGTH_SIZE) {
|
||||
throw new PasswordTooLongException();
|
||||
}
|
||||
|
||||
// If tomcat is behind a reverse proxy, ip needs to be found in other header.
|
||||
String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER);
|
||||
if (remoteIp == null || remoteIp.isEmpty()) {
|
||||
remoteIp = request.getRemoteAddr();
|
||||
}
|
||||
logger.debug("Remote address" + remoteIp);
|
||||
// If tomcat is behind a reverse proxy, ip needs to be found in other header.
|
||||
String remoteIp = request.getHeader(REAL_IP_ADDRESS_HEADER);
|
||||
if (remoteIp == null || remoteIp.isEmpty()) {
|
||||
remoteIp = request.getRemoteAddr();
|
||||
}
|
||||
logger.debug("Remote address" + remoteIp);
|
||||
|
||||
verify(registration, remoteIp);
|
||||
verify(registration, remoteIp);
|
||||
|
||||
final User user = new User();
|
||||
user.setEmail(registration.getEmail().trim());
|
||||
user.setFirstname(registration.getFirstname());
|
||||
user.setLastname(registration.getLastname());
|
||||
user.setPassword(registration.getPassword());
|
||||
final User user = new User();
|
||||
user.setEmail(registration.getEmail().trim());
|
||||
user.setFirstname(registration.getFirstname());
|
||||
user.setLastname(registration.getLastname());
|
||||
user.setPassword(registration.getPassword());
|
||||
|
||||
user.setAuthenticationType(AuthenticationType.DATABASE);
|
||||
userService.createUser(user, false, true);
|
||||
response.setHeader("Location", "/api/restful/users/" + user.getId());
|
||||
}
|
||||
user.setAuthenticationType(AuthenticationType.DATABASE);
|
||||
userService.createUser(user, false, true);
|
||||
response.setHeader("Location", "/api/restful/users/" + user.getId());
|
||||
response.setHeader("ResourceId", Integer.toString(user.getId()));
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = { "application/json" })
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException {
|
||||
try {
|
||||
return userService.resetPassword(email);
|
||||
} catch (InvalidUserEmailException e) {
|
||||
throw new EmailNotExistsException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress)
|
||||
throws BindException {
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/resetPassword", produces = {"application/json"})
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public RestResetPasswordResponse resetPassword(@RequestParam String email) throws InvalidAuthSchemaException, EmailNotExistsException {
|
||||
try {
|
||||
return userService.resetPassword(email);
|
||||
} catch (InvalidUserEmailException e) {
|
||||
throw new EmailNotExistsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
final BindException errors = new RegistrationException(registration, "registration");
|
||||
final UserValidator validator = new UserValidator();
|
||||
validator.setUserService(userService);
|
||||
validator.validate(registration, errors);
|
||||
private void verify(@NotNull final RestUserRegistration registration, @NotNull String remoteAddress)
|
||||
throws BindException {
|
||||
|
||||
// If captcha is enabled, generate it ...
|
||||
if (recatchaEnabled) {
|
||||
final String recaptcha = registration.getRecaptcha();
|
||||
if (recaptcha != null) {
|
||||
final String reCaptchaResponse = captchaService.verifyRecaptcha(remoteAddress, recaptcha);
|
||||
if (reCaptchaResponse != null && !reCaptchaResponse.isEmpty()) {
|
||||
errors.rejectValue("recaptcha", reCaptchaResponse);
|
||||
}
|
||||
} else {
|
||||
errors.rejectValue("recaptcha", Messages.CAPTCHA_LOADING_ERROR);
|
||||
}
|
||||
} else {
|
||||
logger.warn("captchaEnabled is enabled.Recommend to enable it for production environments.");
|
||||
}
|
||||
final BindException errors = new RegistrationException(registration, "registration");
|
||||
final UserValidator validator = new UserValidator();
|
||||
validator.setUserService(userService);
|
||||
validator.validate(registration, errors);
|
||||
|
||||
if (errors.hasErrors()) {
|
||||
throw errors;
|
||||
}
|
||||
// If captcha is enabled, generate it ...
|
||||
if (recatchaEnabled) {
|
||||
final String recaptcha = registration.getRecaptcha();
|
||||
if (recaptcha != null) {
|
||||
final String reCaptchaResponse = captchaService.verifyRecaptcha(remoteAddress, recaptcha);
|
||||
if (reCaptchaResponse != null && !reCaptchaResponse.isEmpty()) {
|
||||
errors.rejectValue("recaptcha", reCaptchaResponse);
|
||||
}
|
||||
} else {
|
||||
errors.rejectValue("recaptcha", Messages.CAPTCHA_LOADING_ERROR);
|
||||
}
|
||||
} else {
|
||||
logger.warn("captchaEnabled is enabled.Recommend to enable it for production environments.");
|
||||
}
|
||||
|
||||
// Is excluded ?.
|
||||
final List<String> excludedDomains = Arrays.asList(domainBanExclusion.split(","));
|
||||
final String emailDomain = registration.getEmail().split("@")[1];
|
||||
if (excludedDomains.contains(emailDomain)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Email is part of ban exclusion list due to abuse. Please, contact site admin if you think this is an error."
|
||||
+ emailDomain);
|
||||
}
|
||||
}
|
||||
if (errors.hasErrors()) {
|
||||
throw errors;
|
||||
}
|
||||
|
||||
// Is excluded ?.
|
||||
final List<String> excludedDomains = Arrays.asList(domainBanExclusion.split(","));
|
||||
final String emailDomain = registration.getEmail().split("@")[1];
|
||||
if (excludedDomains.contains(emailDomain)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Email is part of ban exclusion list due to abuse. Please, contact site admin if you think this is an error."
|
||||
+ emailDomain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright [2022] [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.rest.model;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.wisemapping.exceptions.InvalidMindmapException;
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.model.*;
|
||||
import com.wisemapping.util.TimeUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
@JsonAutoDetect(
|
||||
fieldVisibility = JsonAutoDetect.Visibility.NONE,
|
||||
setterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY,
|
||||
isGetterVisibility = JsonAutoDetect.Visibility.NONE,
|
||||
getterVisibility = JsonAutoDetect.Visibility.PUBLIC_ONLY
|
||||
)
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class RestMindmapMetadata {
|
||||
|
||||
public RestMindmapMetadata() throws WiseMappingException {
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@ import io.jsonwebtoken.security.Keys;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -37,15 +38,18 @@ public class JwtTokenUtil implements Serializable {
|
|||
return Keys.hmacShaKeyFor(Decoders.BASE64.decode(jwtSecret));
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public String extractFromJwtToken(String token) {
|
||||
return Jwts.parserBuilder().setSigningKey(key()).build()
|
||||
.parseClaimsJws(token).getBody().getSubject();
|
||||
}
|
||||
|
||||
public boolean validateJwtToken(@NotNull String authToken) {
|
||||
boolean result = false;
|
||||
try {
|
||||
Jwts.parserBuilder().setSigningKey(key()).build().parse(authToken);
|
||||
return true;
|
||||
result = true;
|
||||
} catch (MalformedJwtException e) {
|
||||
logger.error("Invalid JWT token: {}", e.getMessage());
|
||||
} catch (ExpiredJwtException e) {
|
||||
|
@ -56,6 +60,7 @@ public class JwtTokenUtil implements Serializable {
|
|||
logger.error("JWT claims string is empty: {}", e.getMessage());
|
||||
}
|
||||
|
||||
return false;
|
||||
logger.trace("Is JWT token valid:" + result);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -38,21 +38,18 @@ public final class MailerService {
|
|||
|
||||
//~ Instance fields ......................................................................................
|
||||
|
||||
// @Autowired
|
||||
@Autowired
|
||||
private JavaMailSender mailSender;
|
||||
|
||||
@Autowired
|
||||
private VelocityEngineWrapper velocityEngineWrapper;
|
||||
|
||||
@Value("${mail.serverSendEmail}")
|
||||
@Value("${app.mail.serverSendEmail}")
|
||||
private String serverFromEmail;
|
||||
|
||||
@Value("${mail.supportEmail}")
|
||||
@Value("${app.mail.supportEmail}")
|
||||
private String supportEmail;
|
||||
|
||||
@Value("${mail.errorReporterEmail:}")
|
||||
private String errorReporterEmail;
|
||||
|
||||
//~ Methods ..............................................................................................
|
||||
|
||||
public String getServerSenderEmail() {
|
||||
|
@ -86,8 +83,4 @@ public final class MailerService {
|
|||
public String getSupportEmail() {
|
||||
return supportEmail;
|
||||
}
|
||||
|
||||
public String getErrorReporterEmail() {
|
||||
return errorReporterEmail;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright [2022] [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.service;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.util.DigestUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class NotifierFilter {
|
||||
public static final int MAX_CACHE_ENTRY = 500;
|
||||
private final Map<String, String> emailByMd5 = Collections.synchronizedMap(new LinkedHashMap<String, String>() {
|
||||
protected boolean removeEldestEntry(Map.Entry eldest) {
|
||||
return size() > MAX_CACHE_ENTRY;
|
||||
}
|
||||
});
|
||||
|
||||
public boolean hasBeenSend(@NotNull final String email, @NotNull final Map<String, String> model) {
|
||||
|
||||
final StringBuilder buff = new StringBuilder();
|
||||
for (String key : model.keySet()) {
|
||||
if (!key.equals("mapXML")) {
|
||||
buff.append(key);
|
||||
buff.append("=");
|
||||
buff.append(model.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
final String digest = DigestUtils.md5DigestAsHex(buff.toString().getBytes());
|
||||
boolean result = emailByMd5.containsKey(digest);
|
||||
if (!result) {
|
||||
emailByMd5.put(digest, email);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,17 @@
|
|||
# SpringBoot Configuration ...
|
||||
|
||||
spring:
|
||||
mail:
|
||||
host: smtp.example.com
|
||||
port: 25
|
||||
username: setusername
|
||||
password: setpassword
|
||||
properties:
|
||||
mail:
|
||||
smtp:
|
||||
connectiontimeout: 5000
|
||||
timeout: 3000
|
||||
writetimeout: 5000
|
||||
output:
|
||||
ansi:
|
||||
enabled=always:
|
||||
|
@ -38,13 +49,23 @@ logging:
|
|||
root: TRACE
|
||||
|
||||
# Application Configuration.
|
||||
|
||||
app:
|
||||
jwt:
|
||||
secret: dlqxKAg685SaKhsQXIMeM=JWCw3bkl3Ei3Tb7LMlnd19oMd66burPNlJ0Po1qguyjgpakQTk2CN3
|
||||
expirationMin: 10080 # One week
|
||||
admin:
|
||||
user: admin@wisemapping.org
|
||||
mail:
|
||||
serverSendEmail: root@localhost
|
||||
supportEmail: root@localhost
|
||||
# accounts:
|
||||
# exclusion:
|
||||
# domain:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
google:
|
||||
ads:
|
||||
|
@ -56,18 +77,6 @@ google:
|
|||
enabled: true
|
||||
secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
|
||||
siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
mail:
|
||||
password: ''
|
||||
serverSendEmail: root@localhost
|
||||
smtp:
|
||||
auth: false
|
||||
host: localhost
|
||||
port: 25
|
||||
quitwait: false
|
||||
starttls:
|
||||
enable: false
|
||||
supportEmail: root@localhost
|
||||
username: root
|
||||
security:
|
||||
oauth2:
|
||||
google:
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
|
||||
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
|
||||
<property name="host" value="${mail.smtp.host}"/>
|
||||
<property name="port" value="${mail.smtp.port}"/>
|
||||
<property name="protocol" value="smtp"/>
|
||||
<property name="username" value="${mail.username}"/>
|
||||
<property name="password" value="${mail.password}"/>
|
||||
<property name="javaMailProperties">
|
||||
<props>
|
||||
<prop key="mail.smtp.auth">${mail.smtp.auth:false}</prop>
|
||||
<prop key="mail.smtp.starttls.enable">${mail.smtp.starttls.enable:false}</prop>
|
||||
<prop key="mail.smtp.quitwait">${mail.smtp.quitwait:true}</prop>
|
||||
</props>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
|
||||
<property name="defaultEncoding" value="UTF-8"/>
|
||||
<property name="basenames">
|
||||
<list>
|
||||
<value>messages</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
|
@ -18,27 +18,30 @@
|
|||
|
||||
package com.wisemapping.test.rest;
|
||||
|
||||
|
||||
import com.wisemapping.config.common.CommonConfig;
|
||||
import com.wisemapping.config.rest.RestAppConfig;
|
||||
import com.wisemapping.rest.AdminController;
|
||||
import com.wisemapping.rest.MindmapController;
|
||||
import com.wisemapping.rest.UserController;
|
||||
import com.wisemapping.rest.model.RestUser;
|
||||
import com.wisemapping.security.UserDetailsService;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static com.wisemapping.test.rest.RestHelper.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
|
||||
@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, MindmapController.class, AdminController.class, UserController.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@AutoConfigureMockMvc
|
||||
public class RestAccountControllerTest {
|
||||
private static final String ADMIN_USER = "admin@wisemapping.org";
|
||||
private static final String ADMIN_PASSWORD = "test";
|
||||
|
@ -46,6 +49,9 @@ public class RestAccountControllerTest {
|
|||
@Autowired
|
||||
private TestRestTemplate restTemplate;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService service;
|
||||
|
||||
static public RestAccountControllerTest create(@NotNull TestRestTemplate restTemplate) {
|
||||
final RestAccountControllerTest result = new RestAccountControllerTest();
|
||||
result.restTemplate = restTemplate;
|
||||
|
@ -53,27 +59,40 @@ public class RestAccountControllerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void deleteUser() { // Configure media types ...
|
||||
public void deleteAccount() {
|
||||
|
||||
final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON);
|
||||
final TestRestTemplate adminRestTemplate = this.restTemplate.withBasicAuth(ADMIN_USER, ADMIN_PASSWORD);
|
||||
|
||||
final RestUser dummyUser = createDummyUser();
|
||||
createUser(requestHeaders, adminRestTemplate, dummyUser);
|
||||
final RestUser newUser = createDummyUser();
|
||||
createUser(requestHeaders, adminRestTemplate, newUser);
|
||||
|
||||
// Delete user ...
|
||||
final TestRestTemplate dummyTemplate = this.restTemplate.withBasicAuth(dummyUser.getEmail(), "fooPassword");
|
||||
dummyTemplate.delete(BASE_REST_URL + "/account");
|
||||
final TestRestTemplate newUserTemplate = this.restTemplate.withBasicAuth(newUser.getEmail(), newUser.getPassword());
|
||||
final ResponseEntity<String> exchange = newUserTemplate.exchange(BASE_REST_URL + "/account", HttpMethod.DELETE, null, String.class);
|
||||
assertTrue(exchange.getStatusCode().is2xxSuccessful(), exchange.toString());
|
||||
|
||||
// Is the user there ?
|
||||
// Check that the user has been created ...
|
||||
// try {
|
||||
// findUser(requestHeaders, adminTemplate, location);
|
||||
// fail("User could not be deleted !");
|
||||
// } catch (Exception e) {
|
||||
// }
|
||||
// Check that the account has been deleted ...
|
||||
assertThrows(UsernameNotFoundException.class, () -> {
|
||||
service.loadUserByUsername(newUser.getEmail());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void accessAccount() {
|
||||
final HttpHeaders requestHeaders = createHeaders(MediaType.APPLICATION_JSON);
|
||||
final TestRestTemplate adminRestTemplate = this.restTemplate.withBasicAuth(ADMIN_USER, ADMIN_PASSWORD);
|
||||
|
||||
final RestUser newUser = createDummyUser();
|
||||
createUser(requestHeaders, adminRestTemplate, newUser);
|
||||
|
||||
final TestRestTemplate newUserTemplate = this.restTemplate.withBasicAuth(newUser.getEmail(), newUser.getPassword());
|
||||
final ResponseEntity<RestUser> exchange = newUserTemplate.exchange(BASE_REST_URL + "/account", HttpMethod.GET, null, RestUser.class);
|
||||
assertTrue(exchange.getStatusCode().is2xxSuccessful(), exchange.toString());
|
||||
assertEquals(exchange.getBody().getEmail(), newUser.getEmail());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public RestUser createNewUser() {
|
||||
// Configure media types ...
|
||||
|
|
|
@ -22,14 +22,10 @@ package com.wisemapping.test.rest;
|
|||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.wisemapping.config.common.CommonConfig;
|
||||
import com.wisemapping.config.rest.RestAppConfig;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.rest.JwtAuthController;
|
||||
import com.wisemapping.rest.model.RestJwtUser;
|
||||
import com.wisemapping.rest.model.RestUser;
|
||||
import com.wisemapping.rest.model.RestUserRegistration;
|
||||
import com.wisemapping.security.JwtTokenUtil;
|
||||
import com.wisemapping.service.UserService;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
|
@ -38,15 +34,8 @@ import org.springframework.http.MediaType;
|
|||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.MvcResult;
|
||||
|
||||
import static com.wisemapping.test.rest.RestHelper.createDummyUser;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@SpringBootTest(classes = {RestAppConfig.class, CommonConfig.class, JwtAuthController.class})
|
||||
|
|
|
@ -27,22 +27,20 @@ import com.wisemapping.rest.UserController;
|
|||
import com.wisemapping.rest.model.RestUser;
|
||||
import com.wisemapping.rest.model.RestUserRegistration;
|
||||
import com.wisemapping.service.UserService;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import static com.wisemapping.test.rest.RestHelper.createDummyUser;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
|
Loading…
Reference in New Issue