Clean up.
parent
f8b8aea901
commit
eaf03ea28d
|
@ -1,39 +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 com.wisemapping.filter.RequestPropertiesInterceptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackageClasses = RequestPropertiesInterceptor.class)
|
||||
public class InterceptorsConfig implements WebMvcConfigurer {
|
||||
@Autowired
|
||||
private RequestPropertiesInterceptor requestPropertiesInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(@NotNull final InterceptorRegistry registry) {
|
||||
registry.addInterceptor(requestPropertiesInterceptor);
|
||||
}
|
||||
|
||||
}
|
|
@ -8,7 +8,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
|
@ -21,8 +20,7 @@ import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
|
|||
import static org.springframework.security.config.Customizer.withDefaults;
|
||||
|
||||
|
||||
@SpringBootApplication(scanBasePackageClasses = MindmapController.class)
|
||||
@Import({InterceptorsConfig.class})
|
||||
@SpringBootApplication(scanBasePackageClasses = {MindmapController.class, JwtAuthenticationFilter.class})
|
||||
@EnableWebSecurity
|
||||
public class RestAppConfig {
|
||||
|
||||
|
@ -43,12 +41,13 @@ public class RestAppConfig {
|
|||
.securityMatcher("/**")
|
||||
.addFilterAfter(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(mvc.pattern("/error")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/authenticate")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/users/")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/maps/*/document/xml-pub")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/users/resetPassword")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/oauth2/googlecallback")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/oauth2/confirmaccountsync")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/oauth2/googlecallback")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/oauth2/confirmaccountsync")).permitAll()
|
||||
.requestMatchers(mvc.pattern("/api/restful/admin/**")).hasAnyRole("ADMIN")
|
||||
.requestMatchers(mvc.pattern("/**")).hasAnyRole("USER", "ADMIN")
|
||||
.anyRequest().authenticated()
|
||||
|
|
|
@ -1,79 +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.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.FilterConfig;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* If your wisemapping customization throws cross domain errores in browser, you can configure this filter in webdefault.xml
|
||||
* By default it will accept all domains, but you can restrict to the domain you need
|
||||
*
|
||||
* <filter>
|
||||
* <filter-name>cross-origin</filter-name>
|
||||
* <filter-class>com.wisemapping.filter.CorsFilter</filter-class>
|
||||
* <init-param>
|
||||
* <param-name>allowedOrigins</param-name>
|
||||
* <param-value>*</param-value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <param-name>allowedMethods</param-name>
|
||||
* <param-value>GET,POST,HEAD</param-value>
|
||||
* </init-param>
|
||||
* <init-param>
|
||||
* <param-name>allowedHeaders</param-name>
|
||||
* <param-value>X-Requested-With,Content-Type,Accept,Origin</param-value>
|
||||
* </init-param>
|
||||
* </filter>
|
||||
* <filter-mapping>
|
||||
* <filter-name>cross-origin</filter-name>
|
||||
* <url-pattern>/*</url-pattern>
|
||||
* </filter-mapping>
|
||||
*
|
||||
*/
|
||||
public class CorsFilter implements Filter {
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
if (servletResponse != null) {
|
||||
// Authorize (allow) all domains to consume the content
|
||||
((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Origin", "*");
|
||||
((HttpServletResponse) servletResponse).addHeader("Access-Control-Allow-Methods","GET, OPTIONS, HEAD, PUT, POST");
|
||||
}
|
||||
|
||||
chain.doFilter(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ 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.http.HttpHeaders;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
@ -22,10 +22,10 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.wisemapping.security.JwtTokenUtil.BEARER_TOKEN_PREFIX;
|
||||
|
||||
@Component
|
||||
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
private static final String BEARER_TOKEN_PREFIX = "Bearer ";
|
||||
private static final String AUTHORIZATION_HEADER = "Authorization";
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
|
@ -35,7 +35,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
final private static Logger logger = LogManager.getLogger();
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
|
||||
protected void doFilterInternal(@NotNull final HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
final Optional<String> token = getJwtTokenFromRequest(request);
|
||||
|
||||
|
@ -62,7 +62,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
private Optional<String> extractEmailFromToken(final @NotNull String token) {
|
||||
Optional<String> result = Optional.empty();
|
||||
try {
|
||||
result = Optional.of(jwtTokenUtil.extractFromJwtToken(token));
|
||||
result = Optional.ofNullable(jwtTokenUtil.extractFromJwtToken(token));
|
||||
} catch (Exception e) {
|
||||
// Handle token extraction/validation errors
|
||||
logger.debug("Error extracting email from token: " + e.getMessage());
|
||||
|
@ -74,7 +74,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
private static Optional<String> getJwtTokenFromRequest(@NotNull HttpServletRequest request) {
|
||||
Optional<String> result = Optional.empty();
|
||||
|
||||
final String authorizationHeader = request.getHeader(AUTHORIZATION_HEADER);
|
||||
final String authorizationHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
|
||||
if (authorizationHeader != null) {
|
||||
if (authorizationHeader.startsWith(BEARER_TOKEN_PREFIX)) {
|
||||
logger.trace("JWT Bearer token found.");
|
||||
|
|
|
@ -1,83 +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.filter;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
@Component
|
||||
public class RequestPropertiesInterceptor implements HandlerInterceptor {
|
||||
@Value("${google.analytics.enabled}")
|
||||
private Boolean analyticsEnabled;
|
||||
|
||||
@Value("${google.analytics.account}")
|
||||
private String analyticsAccount;
|
||||
|
||||
@Value("${google.recaptcha2.enabled}")
|
||||
private Boolean recaptcha2Enabled;
|
||||
|
||||
@Value("${site.static.js.url}")
|
||||
private String siteStaticUrl;
|
||||
|
||||
@Value("${google.recaptcha2.siteKey}")
|
||||
private String recaptcha2SiteKey;
|
||||
|
||||
@Value("${google.ads.enabled}")
|
||||
private Boolean adsEnabled;
|
||||
|
||||
@Value("${site.homepage}")
|
||||
private String siteHomepage;
|
||||
|
||||
@Value("${site.baseurl:}")
|
||||
private String siteUrl;
|
||||
|
||||
@Value("${security.oauth2.google.url}")
|
||||
private String googleOauth2Url;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, Object object) throws Exception {
|
||||
|
||||
request.setAttribute("google.analytics.enabled", analyticsEnabled);
|
||||
request.setAttribute("google.analytics.account", analyticsAccount);
|
||||
request.setAttribute("google.ads.enabled", adsEnabled);
|
||||
|
||||
request.setAttribute("google.recaptcha2.enabled", recaptcha2Enabled);
|
||||
request.setAttribute("google.recaptcha2.siteKey", recaptcha2SiteKey);
|
||||
|
||||
request.setAttribute("security.oauth2.google.url", googleOauth2Url);
|
||||
|
||||
request.setAttribute("site.homepage", siteHomepage);
|
||||
request.setAttribute("site.static.js.url", siteStaticUrl);
|
||||
|
||||
request.setAttribute("security.type", "db");
|
||||
|
||||
// If the property could not be resolved, try to infer one from the request...
|
||||
if (siteUrl.isBlank()) {
|
||||
siteUrl = request.getRequestURL().toString().replace(request.getRequestURI(), request.getContextPath());
|
||||
}
|
||||
request.setAttribute("site.baseurl", siteUrl);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -164,7 +164,7 @@ public class User
|
|||
}
|
||||
|
||||
public Boolean getGoogleSync() {
|
||||
return googleSync;
|
||||
return googleSync!=null && googleSync;
|
||||
}
|
||||
|
||||
public void setGoogleSync(Boolean googleSync) {
|
||||
|
|
|
@ -18,24 +18,18 @@
|
|||
|
||||
package com.wisemapping.rest;
|
||||
|
||||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.rest.model.RestJwtUser;
|
||||
import com.wisemapping.security.JwtTokenUtil;
|
||||
import com.wisemapping.security.UserDetailsService;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.DisabledException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
|
@ -45,37 +39,23 @@ public class JwtAuthController {
|
|||
@Autowired
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
|
||||
public ResponseEntity<?> createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws Exception {
|
||||
|
||||
public ResponseEntity<String> createAuthenticationToken(@RequestBody RestJwtUser user, @NotNull HttpServletResponse response) throws WiseMappingException {
|
||||
// Is a valid user ?
|
||||
authenticate(user.getEmail(), user.getPassword());
|
||||
final String result = jwtTokenUtil.doLogin(response, user.getEmail());
|
||||
|
||||
// Create token ...
|
||||
final UserDetails userDetails = userDetailsService
|
||||
.loadUserByUsername(user.getEmail());
|
||||
|
||||
final String token = jwtTokenUtil.generateJwtToken(userDetails);
|
||||
|
||||
// Add token in the header ...
|
||||
response.addHeader(HttpHeaders.AUTHORIZATION, "Bearer " + token);
|
||||
|
||||
return ResponseEntity.ok(token);
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
|
||||
private void authenticate(@NotNull String username, @NotNull String password) throws Exception {
|
||||
private void authenticate(@NotNull String username, @NotNull String password) throws WiseMappingException {
|
||||
try {
|
||||
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
|
||||
} catch (DisabledException e) {
|
||||
throw new Exception("USER_DISABLED", e);
|
||||
} catch (BadCredentialsException e) {
|
||||
throw new Exception("INVALID_CREDENTIALS", e);
|
||||
} catch (DisabledException | BadCredentialsException e) {
|
||||
throw new WiseMappingException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -21,24 +21,20 @@ package com.wisemapping.rest;
|
|||
import com.wisemapping.exceptions.WiseMappingException;
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.rest.model.RestOath2CallbackResponse;
|
||||
import com.wisemapping.service.*;
|
||||
import com.wisemapping.security.JwtTokenUtil;
|
||||
import com.wisemapping.service.UserService;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpSession;
|
||||
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/oauth2/")
|
||||
@CrossOrigin
|
||||
public class OAuth2Controller extends BaseController {
|
||||
@Qualifier("userService")
|
||||
|
@ -49,40 +45,36 @@ public class OAuth2Controller extends BaseController {
|
|||
@Autowired
|
||||
private AuthenticationManager authManager;
|
||||
|
||||
@Value("${google.recaptcha2.enabled}")
|
||||
private Boolean recatchaEnabled;
|
||||
@Autowired
|
||||
private JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
@Value("${accounts.exclusion.domain:''}")
|
||||
private String domainBanExclusion;
|
||||
|
||||
private void doLogin(HttpServletRequest request, String email) {
|
||||
PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken(email,null);
|
||||
Authentication auth = authManager.authenticate(token);
|
||||
SecurityContextHolder.getContext().setAuthentication(auth);
|
||||
// update spring mvc session
|
||||
HttpSession session = request.getSession(true);
|
||||
session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.POST, value = "/oauth2/googlecallback", produces = { "application/json" })
|
||||
@RequestMapping(method = RequestMethod.POST, value = "googlecallback", produces = {"application/json"})
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||
User user = userService.createUserFromGoogle(code);
|
||||
if (user.getGoogleSync() != null && user.getGoogleSync()) {
|
||||
doLogin(request, user.getEmail());
|
||||
}
|
||||
RestOath2CallbackResponse response = new RestOath2CallbackResponse();
|
||||
response.setEmail(user.getEmail());
|
||||
response.setGoogleSync(user.getGoogleSync());
|
||||
response.setSyncCode(user.getSyncCode());
|
||||
return response;
|
||||
public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletResponse response, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||
User user = userService.createAndAuthUserFromGoogle(code);
|
||||
if (user.getGoogleSync()) {
|
||||
jwtTokenUtil.doLogin(response, user.getEmail());
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "/oauth2/confirmaccountsync", produces = { "application/json" })
|
||||
// Response ...
|
||||
final RestOath2CallbackResponse result = new RestOath2CallbackResponse();
|
||||
result.setEmail(user.getEmail());
|
||||
result.setGoogleSync(user.getGoogleSync());
|
||||
result.setSyncCode(user.getSyncCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@RequestMapping(method = RequestMethod.PUT, value = "confirmaccountsync", produces = {"application/json"})
|
||||
@ResponseStatus(value = HttpStatus.OK)
|
||||
public void confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException {
|
||||
public void confirmAccountSync(@NotNull @RequestParam String email, @NotNull @RequestParam String code, @NotNull HttpServletResponse response) throws WiseMappingException {
|
||||
// Authenticate ...
|
||||
userService.createAndAuthUserFromGoogle(code);
|
||||
|
||||
// Update login
|
||||
userService.confirmAccountSync(email, code);
|
||||
doLogin(request, email);
|
||||
}
|
||||
|
||||
// Add header ...
|
||||
jwtTokenUtil.doLogin(response, email);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,14 @@ package com.wisemapping.security;
|
|||
import io.jsonwebtoken.*;
|
||||
import io.jsonwebtoken.io.Decoders;
|
||||
import io.jsonwebtoken.security.Keys;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
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.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -18,6 +21,8 @@ import java.util.Date;
|
|||
@Component
|
||||
public class JwtTokenUtil implements Serializable {
|
||||
final private Logger logger = LogManager.getLogger();
|
||||
public final static String BEARER_TOKEN_PREFIX = "Bearer ";
|
||||
|
||||
|
||||
@Value("${app.jwt.secret}")
|
||||
private String jwtSecret;
|
||||
|
@ -25,6 +30,10 @@ public class JwtTokenUtil implements Serializable {
|
|||
@Value("${app.jwt.expirationMin}")
|
||||
private int jwtExpirationMin;
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
|
||||
public String generateJwtToken(@NotNull final UserDetails user) {
|
||||
return Jwts.builder()
|
||||
.setSubject((user.getUsername()))
|
||||
|
@ -63,4 +72,15 @@ public class JwtTokenUtil implements Serializable {
|
|||
logger.trace("Is JWT token valid:" + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String doLogin(@NotNull HttpServletResponse response, @NotNull String email) {
|
||||
final UserDetails userDetails = userDetailsService.loadUserByUsername(email);
|
||||
|
||||
// Add JWT in the HTTP header ...
|
||||
final String token = generateJwtToken(userDetails);
|
||||
response.addHeader(HttpHeaders.AUTHORIZATION, BEARER_TOKEN_PREFIX + token);
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
|
@ -30,7 +30,7 @@ public interface UserService {
|
|||
|
||||
User createUser(@NotNull User user, boolean emailConfirmEnabled, boolean welcomeEmail) throws WiseMappingException;
|
||||
|
||||
User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException;
|
||||
User createAndAuthUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException;
|
||||
|
||||
User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException;
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@ public class UserServiceImpl
|
|||
final Mindmap mindMap = buildTutorialMindmap(user.getFirstname());
|
||||
mindmapService.addMindmap(mindMap, user);
|
||||
|
||||
|
||||
// Send registration email.
|
||||
if (emailConfirmEnabled) {
|
||||
notificationService.sendRegistrationEmail(user);
|
||||
|
@ -174,7 +173,7 @@ public class UserServiceImpl
|
|||
}
|
||||
|
||||
@NotNull
|
||||
public User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException {
|
||||
public User createAndAuthUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException {
|
||||
GoogleAccountBasicData data;
|
||||
try {
|
||||
data = googleService.processCallback(callbackCode);
|
||||
|
@ -185,7 +184,7 @@ public class UserServiceImpl
|
|||
User existingUser = userManager.getUserBy(data.getEmail());
|
||||
if (existingUser == null) {
|
||||
User newUser = new User();
|
||||
// new registrations from google starts synched
|
||||
// new registrations from google starts sync
|
||||
newUser.setGoogleSync(true);
|
||||
newUser.setEmail(data.getEmail());
|
||||
newUser.setFirstname(data.getName());
|
||||
|
@ -208,7 +207,7 @@ public class UserServiceImpl
|
|||
}
|
||||
|
||||
public User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException {
|
||||
User existingUser = userManager.getUserBy(email);
|
||||
final User existingUser = userManager.getUserBy(email);
|
||||
// additional security check
|
||||
if (existingUser == null || !existingUser.getSyncCode().equals(code)) {
|
||||
throw new WiseMappingException("User not found / incorrect code");
|
||||
|
|
|
@ -34,15 +34,15 @@ import com.wisemapping.service.google.http.HttpInvokerException;
|
|||
public class GoogleService {
|
||||
@Autowired
|
||||
private HttpInvoker httpInvoker;
|
||||
@Value("${security.oauth2.google.confirmUrl:}")
|
||||
@Value("${app.security.oauth2.google.confirmUrl:}")
|
||||
private String optinConfirmUrl;
|
||||
@Value("${security.oauth2.google.userinfoUrl:}")
|
||||
@Value("${app.security.oauth2.google.userinfoUrl:}")
|
||||
private String accountBasicDataUrl;
|
||||
@Value("${security.oauth2.google.clientId:}")
|
||||
@Value("${app.security.oauth2.google.clientId:}")
|
||||
private String clientId;
|
||||
@Value("${security.oauth2.google.clientSecret:}")
|
||||
@Value("${app.security.oauth2.google.clientSecret:}")
|
||||
private String clientSecret;
|
||||
@Value("${security.oauth2.google.callbackUrl:}")
|
||||
@Value("${app.security.oauth2.google.callbackUrl:}")
|
||||
private String callbackUrl;
|
||||
|
||||
public void setHttpInvoker(HttpInvoker httpInvoker) {
|
||||
|
@ -108,8 +108,9 @@ public class GoogleService {
|
|||
|
||||
public GoogleAccountBasicData processCallback(final String code)
|
||||
throws HttpInvokerException {
|
||||
Map<String, String> body = this.getOptinConfirmBody(code);
|
||||
JsonNode optionConfirmResponse = httpInvoker.invoke(
|
||||
|
||||
final Map<String, String> body = this.getOptinConfirmBody(code);
|
||||
final JsonNode optionConfirmResponse = httpInvoker.invoke(
|
||||
optinConfirmUrl,
|
||||
HttpInvokerContentType.FORM_ENCODED,
|
||||
HttpMethod.POST,
|
||||
|
@ -120,7 +121,7 @@ public class GoogleService {
|
|||
final String accessToken = getNodeAsString(optionConfirmResponse, "access_token");
|
||||
final String refreshToken = getNodeAsString(optionConfirmResponse, "refresh_token");
|
||||
|
||||
GoogleAccountBasicData data = this.getAccountBasicData(accessToken);
|
||||
final GoogleAccountBasicData data = this.getAccountBasicData(accessToken);
|
||||
data.setAccessToken(accessToken);
|
||||
data.setRefreshToken(refreshToken);
|
||||
return data;
|
||||
|
|
|
@ -1,46 +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.webmvc;
|
||||
|
||||
import com.wisemapping.model.User;
|
||||
import com.wisemapping.security.Utils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
@Controller
|
||||
@PreAuthorize("permitAll()")
|
||||
public class MvcLoginController {
|
||||
|
||||
|
||||
@RequestMapping(value = "c/login", method = RequestMethod.GET)
|
||||
protected ModelAndView showLoginPage() {
|
||||
final User user = Utils.getUser(false);
|
||||
ModelAndView result;
|
||||
if (user != null) {
|
||||
result = new ModelAndView("forward:/c/maps/");
|
||||
} else {
|
||||
result = new ModelAndView("reactInclude");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -60,15 +60,28 @@ app:
|
|||
mail:
|
||||
serverSendEmail: root@localhost
|
||||
supportEmail: root@localhost
|
||||
|
||||
#######################################################################################
|
||||
# Google OAuth Authentication
|
||||
#######################################################################################
|
||||
# OAuth Client id
|
||||
#security.oauth2.google.clientId=<config settings>
|
||||
# OAuth Client secret
|
||||
#security.oauth2.google.clientSecret=<oauth client>
|
||||
# Redirect to this url, this url must be configured in the google app {baseurl}/c/registration-google
|
||||
#security.oauth2.google.callbackUrl=<oauth callback url>
|
||||
security:
|
||||
oauth2:
|
||||
google:
|
||||
confirmUrl: https://oauth2.googleapis.com/token
|
||||
userinfoUrl: https://www:googleapis.com/oauth2/v3/userinfo
|
||||
url: https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=${app.security.oauth2.google.callbackUrl}&prompt=consent&response_type=code&client_id=${app.security.oauth2.google.clientId}&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&access_type=offline&state=wisemapping&include_granted_scopes=true
|
||||
|
||||
# accounts:
|
||||
# exclusion:
|
||||
# domain:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
google:
|
||||
ads:
|
||||
enabled: false
|
||||
|
@ -79,12 +92,6 @@ google:
|
|||
enabled: true
|
||||
secretKey: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
|
||||
siteKey: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI
|
||||
security:
|
||||
oauth2:
|
||||
google:
|
||||
confirmUrl: https://oauth2.googleapis.com/token
|
||||
url: https//review
|
||||
userinfoUrl: https://www.googleapis.com/oauth2/v3/userinfo
|
||||
site:
|
||||
homepage: c/login
|
||||
static:
|
||||
|
|
Loading…
Reference in New Issue