commit 4afeda3da3a839152df38dc22d08a82307b10e01
Author: Jakub Smid <jaksmid@seznam.cz>
Date:   Fri Apr 15 09:25:17 2022 +0200

    Checked, added and fixed rights to endpoints
    
    re #9511

diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/security/SecurityConfig.java b/backend/src/main/java/cz/zcu/kiv/backendapi/security/SecurityConfig.java
index d6883d7..07c9f0d 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/security/SecurityConfig.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/security/SecurityConfig.java
@@ -21,6 +21,9 @@ import org.springframework.web.cors.CorsConfiguration;
 import org.springframework.web.cors.CorsConfigurationSource;
 import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Security config class
  */
@@ -28,6 +31,12 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
 @EnableWebSecurity
 @RequiredArgsConstructor
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
+
+    /**
+     * Map of permitted endpoints with HTTP method (user does not need to be authenticated perform the request)
+     */
+    private static final Map<String, HttpMethod> PERMITTED_ENDPOINTS;
+
     /**
      * User detail service
      */
@@ -43,11 +52,17 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
      */
     private final JwtUtils jwtUtils;
 
-    /**
-     * List of permitted pages without login
-     */
-    private final String[] permittedUrls = new String[]{"/login", "/users/token", "/swagger-ui/**",
-            "/swagger-ui.html", "/v3/api-docs", "/v3/api-docs/swagger-config"};
+    static {
+        PERMITTED_ENDPOINTS = new HashMap<>();
+        PERMITTED_ENDPOINTS.put("/login", HttpMethod.POST);
+        PERMITTED_ENDPOINTS.put("/users/token", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/swagger-ui/**", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/swagger-ui.html", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/v3/api-docs", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/v3/api-docs/swagger-config", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/catalog-items", HttpMethod.GET);
+        PERMITTED_ENDPOINTS.put("/catalog-items/**", HttpMethod.GET);
+    }
 
     /**
      * Security configuration
@@ -55,6 +70,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
      * @param http http security
      * @throws Exception exception
      */
+    // TODO configure and check rights
     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http.csrf().disable()
@@ -63,14 +79,17 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
                 .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                 .and()
                 .addFilter(new JwtUsernameAndPasswordAuthenticationFilter(authenticationManager(), jwtUtils))
-                .addFilterAfter(new JwtTokenVerifier(jwtUtils, permittedUrls), JwtUsernameAndPasswordAuthenticationFilter.class)
+                .addFilterAfter(new JwtTokenVerifier(jwtUtils, PERMITTED_ENDPOINTS), JwtUsernameAndPasswordAuthenticationFilter.class)
                 .authorizeRequests()
-                .antMatchers(permittedUrls).permitAll()
-                .antMatchers("/user/update-permissions/**", "/user/reset-password/**").hasRole(Role.ADMIN.name())
-                .antMatchers(HttpMethod.DELETE, "/user/**").hasRole(Role.ADMIN.name())
-                .antMatchers("/write/**").hasAuthority(Permission.WRITE.name())
-                .antMatchers("/read/**").hasAuthority(Permission.READ.name())
-                .antMatchers("/delete/**").hasAuthority(Permission.DELETE.name())
+                .antMatchers(HttpMethod.GET, PERMITTED_ENDPOINTS.keySet().stream().filter(k -> PERMITTED_ENDPOINTS.get(k).equals(HttpMethod.GET)).toArray(String[]::new)).permitAll()
+                .antMatchers(HttpMethod.POST, "/login").permitAll()
+                .antMatchers(HttpMethod.PATCH, "/users/*/permissions", "/users/*/password").hasRole(Role.ADMIN.name())
+                .antMatchers(HttpMethod.DELETE, "/users/**").hasRole(Role.ADMIN.name())
+                .antMatchers(HttpMethod.GET, "/users").hasRole(Role.ADMIN.name())
+                .antMatchers(HttpMethod.GET, "/path").hasAuthority(Permission.READ.name())
+                .antMatchers(HttpMethod.POST, "/catalog-items").hasAuthority(Permission.WRITE.name())
+                .antMatchers(HttpMethod.PUT, "/catalog-items/*").hasAuthority(Permission.WRITE.name())
+                .antMatchers(HttpMethod.DELETE, "/catalog-items/*").hasAuthority(Permission.DELETE.name())
                 .anyRequest()
                 .authenticated();
     }
diff --git a/backend/src/main/java/cz/zcu/kiv/backendapi/security/jwt/JwtTokenVerifier.java b/backend/src/main/java/cz/zcu/kiv/backendapi/security/jwt/JwtTokenVerifier.java
index fed29b1..fcc0a6b 100644
--- a/backend/src/main/java/cz/zcu/kiv/backendapi/security/jwt/JwtTokenVerifier.java
+++ b/backend/src/main/java/cz/zcu/kiv/backendapi/security/jwt/JwtTokenVerifier.java
@@ -8,6 +8,7 @@ import com.google.common.base.Strings;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -19,9 +20,9 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 import java.util.stream.Collectors;
 
 
@@ -38,9 +39,9 @@ public class JwtTokenVerifier extends OncePerRequestFilter {
     private final JwtUtils jwtUtils;
 
     /**
-     * Array or urls with this filter (JWT not needed for them)
+     * Map of permitted endpoints with HTTP method (user does not need to be authenticated perform the request)
      */
-    private final String[] skipFilterUrls;
+    private final Map<String, HttpMethod> skipFilterEndpoints;
 
     /**
      * Filters request - checks for JWT token and validates it
@@ -83,10 +84,9 @@ public class JwtTokenVerifier extends OncePerRequestFilter {
      *
      * @param request request
      * @return true if given request should not be scanned for JWT, false otherwise
-     * @throws ServletException servlet exception
      */
     @Override
-    protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException {
-        return Arrays.stream(skipFilterUrls).anyMatch(url -> new AntPathRequestMatcher(url).matches(request));
+    protected boolean shouldNotFilter(HttpServletRequest request) {
+        return skipFilterEndpoints.entrySet().stream().anyMatch(e -> new AntPathRequestMatcher(e.getKey(), e.getValue().toString()).matches(request));
     }
 }
