commit 59e25e67d54b90c12dcdfe2da1c1ddc4e55ff4d7
Author: Petr Urban <urbanp@gapps.zcu.cz>
Date:   Sat Apr 15 13:00:25 2023 +0200

    #10365 - vytváření endpointu pro refresh tokenu. Token se vytvoří nový s platností na 1 h a starý se znevaliduje.

diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..03d9549
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <profile version="1.0">
+    <option name="myName" value="Project Default" />
+    <inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
+  </profile>
+</component>
\ No newline at end of file
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/config/WebConfig.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/config/WebConfig.java
index 1105b76..fe2b1c8 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/config/WebConfig.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/config/WebConfig.java
@@ -13,7 +13,9 @@ public class WebConfig {
         return new WebMvcConfigurer() {
             @Override
             public void addCorsMappings(CorsRegistry registry) {
-                registry.addMapping("/**").allowedOrigins("*");
+                registry.addMapping("/**")
+                        .allowedOrigins("http://localhost:3000")
+                        .allowCredentials(true);
             }
         };
     }
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserController.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserController.java
index a61cb3e..94b9272 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserController.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/controller/UserController.java
@@ -88,6 +88,26 @@ public class UserController {
         return aOuthService.logoutUser(user);
     }
 
+    @GetMapping("/refresh")
+    public ResponseEntity<String> refreshToken(@RequestHeader HttpHeaders headers) {
+        final String authHeader = headers.getFirst(HttpHeaders.AUTHORIZATION);
+        if (authHeader == null || !authHeader.startsWith("Bearer")) {
+            // err
+        }
+        final String token = authHeader.substring(7);
+
+        String jwtToken = null;
+        ResponseEntity<String> response = aOuthService.refreshToken(token);
+
+        if (response.getStatusCode().is2xxSuccessful()) {
+            jwtToken = response.getBody();
+            return getResponseEntity(UserModelStatusCodes.TOKEN_REFRESHED,jwtToken);
+        }
+
+        return getResponseEntity(UserModelStatusCodes.TOKEN_EXPIRED, UserModelStatusCodes.TOKEN_EXPIRED.getLabel());
+
+    }
+
     /**
      * Method to create response
      *
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/httpExceptions/CustomExceptionHandler.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/httpExceptions/CustomExceptionHandler.java
new file mode 100644
index 0000000..a5a1319
--- /dev/null
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/httpExceptions/CustomExceptionHandler.java
@@ -0,0 +1,17 @@
+package cz.zcu.fav.kiv.antipatterndetectionapp.v2.httpExceptions;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.client.HttpClientErrorException;
+
+@ControllerAdvice
+public class CustomExceptionHandler {
+
+    @ExceptionHandler(HttpClientErrorException.Unauthorized.class)
+    public ResponseEntity<String> handleUnauthorizedException(HttpClientErrorException.Unauthorized ex) {
+        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(ex.getResponseBodyAsString());
+    }
+
+}
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/JwtAuthenticationFilter.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/JwtAuthenticationFilter.java
index ac9efa7..d21228c 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/JwtAuthenticationFilter.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/JwtAuthenticationFilter.java
@@ -1,5 +1,6 @@
 package cz.zcu.fav.kiv.antipatterndetectionapp.v2.security;
 
+import cz.zcu.fav.kiv.antipatterndetectionapp.v2.httpExceptions.CustomExceptionHandler;
 import cz.zcu.fav.kiv.antipatterndetectionapp.v2.service.OAuthService;
 import org.springframework.http.*;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
@@ -59,12 +60,18 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
             }*/
         } catch (Exception e) {
             SecurityContextHolder.clearContext();
-            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
             response.getOutputStream().println("{\"error\" : \"Some other error related to jwt token!\"}");
             return;
         }
 
         chain.doFilter(request, response);
     }
+
+    @Override
+    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
+            String path = request.getRequestURI().substring(request.getContextPath().length());
+        return path.startsWith("/v2/user/");
+    }
 }
 
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
index 7f92112..19dc2bf 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/security/WebSecurityConfig.java
@@ -64,18 +64,13 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
         httpSecurity
                 .csrf().disable()
                 .authorizeRequests()
-                .antMatchers("/v2/user/register", "/v2/user/login").permitAll()
+                .mvcMatchers("/v2/user/register", "/v2/user/login", "/v2/user/refresh", "/v2/user/logout").permitAll()
                 .anyRequest().authenticated()
-//                .and()
-//                .exceptionHandling()
-//                .authenticationEntryPoint(new OAuthServiceImpl())
                 .and()
                 .sessionManagement()
                 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                 .and()
                 .addFilterBefore(new JwtAuthenticationFilter(new OAuthServiceImpl()), UsernamePasswordAuthenticationFilter.class);
-//        httpSecurity.addFilterAfter(new JwtAuthenticationFilter(new OAuthServiceImpl()), UsernamePasswordAuthenticationFilter.class);
-//        httpSecurity.addFilter(new JwtAuthenticationFilter(new OAuthServiceImpl()));
     }
 
 }
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthService.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthService.java
index 3ff3d6e..08892f0 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthService.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthService.java
@@ -10,4 +10,7 @@ public interface OAuthService {
     public ResponseEntity<String> authenticate(String token);
     public ResponseEntity<String> loginUser(User user);
     public ResponseEntity<String> logoutUser(User user);
+
+    ResponseEntity<String> refreshToken(String token);
+
 }
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
index e7e88b9..02281e0 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/service/OAuthServiceImpl.java
@@ -44,6 +44,8 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
 //    @Value("${auth.realm.logout}")
     private String AUTH_URL_LOGOUT = "http://localhost:8081/logout";
 
+    private String AUTH_URL_REFRESH = "http://localhost:8081/refresh";
+
     /**
      *
      */
@@ -89,6 +91,11 @@ public class OAuthServiceImpl implements OAuthService, UserDetailsService {
         return RequestBuilder.sendRequestResponse(AUTH_URL_LOGOUT, requestBody);
     }
 
+    @Override
+    public ResponseEntity<String> refreshToken(String token) {
+        return RequestBuilder.sendRequestResponse(AUTH_URL_REFRESH, token, true);
+    }
+
     @Override
     public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
         final User user = this.userService.getUserByName(s);
diff --git a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
index b03fb3f..16abadc 100644
--- a/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
+++ b/src/main/java/cz/zcu/fav/kiv/antipatterndetectionapp/v2/utils/RequestBuilder.java
@@ -44,4 +44,18 @@ public class RequestBuilder {
         return response;
     }
 
+    public static ResponseEntity<String> sendRequestResponse(String url, String token, boolean get) {
+        RestTemplate restTemplate = new RestTemplate();
+
+        HttpHeaders headers = new HttpHeaders();
+
+        headers.setContentType(MediaType.APPLICATION_JSON);
+        //headers.set("X-spade-request",spadeSignature);
+        headers.set(HttpHeaders.AUTHORIZATION, "Bearer " + token);
+
+        HttpEntity<String> entity = new HttpEntity<>(null, headers);
+        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);
+        return response;
+    }
+
 }
