From 59fc7e6f809c67da44b39fb7d8aecbbd1e3d978b Mon Sep 17 00:00:00 2001
From: Thomas <gltron3000@gmail.com>
Date: Sun, 24 May 2020 15:44:09 +0200
Subject: [PATCH] Fixed users roles

---
 .../mozen/auth/JwtAuthenticationFilter.java   |  4 +--
 .../mozen/auth/JwtAuthorizationFilter.java    | 28 ++++++++++------
 .../mozen/auth/JwtUserDetailsService.java     |  6 ++--
 .../src/main/java/mozen/auth/WebSecurity.java | 22 ++++++++++---
 .../java/mozen/business/IUserManager.java     |  6 ++--
 .../main/java/mozen/business/UserManager.java | 22 +++++++++++--
 mozen/src/main/java/mozen/model/Role.java     |  2 +-
 .../main/java/mozen/utils/DatabaseFiller.java |  6 ++--
 mozen/src/main/java/mozen/utils/JwtUtils.java |  7 +++-
 .../src/main/java/mozen/utils/UserHelper.java |  2 +-
 .../main/java/mozen/web/UserController.java   | 32 +++++++++++++++++--
 11 files changed, 104 insertions(+), 33 deletions(-)

diff --git a/mozen/src/main/java/mozen/auth/JwtAuthenticationFilter.java b/mozen/src/main/java/mozen/auth/JwtAuthenticationFilter.java
index 8fa3561..d600d31 100644
--- a/mozen/src/main/java/mozen/auth/JwtAuthenticationFilter.java
+++ b/mozen/src/main/java/mozen/auth/JwtAuthenticationFilter.java
@@ -33,7 +33,7 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte
     try {
       LoginMessage message = new ObjectMapper().readValue(req.getInputStream(), LoginMessage.class);
 
-      System.err.println("Auth user n:"+message.getUsername()+" p:"+message.getPassword());
+      System.err.println("Login user n:"+message.getUsername()+" p:"+message.getPassword());
 
       return authenticationManager.authenticate(
         new UsernamePasswordAuthenticationToken(message.getUsername(), message.getPassword(), new ArrayList<>())
@@ -47,7 +47,7 @@ public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilte
   protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain, Authentication auth) 
   throws IOException, ServletException {
     User user = (User) auth.getPrincipal();
-    String token = JwtUtils.generateToken(user.getUsername());
+    String token = JwtUtils.generateToken(user.getUsername(), user.getAuthorities());
     res.getWriter().write(new ObjectMapper().writeValueAsString(new ResponseMessage(false, token)));
     // res.addHeader("Authorization", "Bearer " + token);
   }
diff --git a/mozen/src/main/java/mozen/auth/JwtAuthorizationFilter.java b/mozen/src/main/java/mozen/auth/JwtAuthorizationFilter.java
index a874066..cebf77d 100644
--- a/mozen/src/main/java/mozen/auth/JwtAuthorizationFilter.java
+++ b/mozen/src/main/java/mozen/auth/JwtAuthorizationFilter.java
@@ -2,7 +2,8 @@ package mozen.auth;
 
 import java.io.IOException;
 import java.security.Key;
-import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.servlet.FilterChain;
 import javax.servlet.ServletException;
@@ -11,9 +12,12 @@ import javax.servlet.http.HttpServletResponse;
 
 import org.springframework.security.authentication.AuthenticationManager;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
 
+import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.Jwts;
 import mozen.utils.JwtUtils;
 
@@ -42,15 +46,19 @@ public class JwtAuthorizationFilter extends BasicAuthenticationFilter {
   private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
     String token = request.getHeader("Authorization");
     if(token != null) {
-      Key key = JwtUtils.generateKey();
-      String username = Jwts.parser()
-        .setSigningKey(key)
-        .parseClaimsJws(token.replace("Bearer ", ""))
-        .getBody()
-        .getSubject();
-
-      if (username != null) {
-        return new UsernamePasswordAuthenticationToken(username, null, new ArrayList<>());
+      try {
+        Key key = JwtUtils.generateKey();
+        Claims claims = Jwts.parser().setSigningKey(key).parseClaimsJws(token.replace("Bearer ", "")).getBody();
+        String username = (String) claims.get("username");
+        String role = (String) claims.get("role");
+        if (username != null && role != null) {
+          System.err.println("Auth user u:"+username+" r:"+role);
+          Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
+          grantedAuthorities.add(new SimpleGrantedAuthority(role));
+          return new UsernamePasswordAuthenticationToken(username, null, grantedAuthorities);
+        }
+      } catch (Exception e) {
+        return null;
       }
 
       return null;
diff --git a/mozen/src/main/java/mozen/auth/JwtUserDetailsService.java b/mozen/src/main/java/mozen/auth/JwtUserDetailsService.java
index a4e2503..2cbd498 100644
--- a/mozen/src/main/java/mozen/auth/JwtUserDetailsService.java
+++ b/mozen/src/main/java/mozen/auth/JwtUserDetailsService.java
@@ -21,11 +21,10 @@ public class JwtUserDetailsService implements UserDetailsService {
 
   @Override
   public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
+    System.err.println("[USER DETAILS] u:"+username);
     mozen.model.User user = manager.getUserByUsername(username);
     if(user == null) throw new UsernameNotFoundException(username);
     
-    Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
-    
     /* 
     // Gestion multi roles
     // Plus propre (Transformer model.Role en Entity et model.User.role en liste de Role)
@@ -34,7 +33,8 @@ public class JwtUserDetailsService implements UserDetailsService {
     }
     */
 
-    grantedAuthorities.add(new SimpleGrantedAuthority(user.getRole().toString()));
+    Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
+    grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+user.getRole().toString()));    
 
     return new User(user.getUsername(), user.getPassword(), grantedAuthorities);
   }  
diff --git a/mozen/src/main/java/mozen/auth/WebSecurity.java b/mozen/src/main/java/mozen/auth/WebSecurity.java
index f59850d..e42b976 100644
--- a/mozen/src/main/java/mozen/auth/WebSecurity.java
+++ b/mozen/src/main/java/mozen/auth/WebSecurity.java
@@ -34,16 +34,30 @@ public class WebSecurity extends WebSecurityConfigurerAdapter{
       .cors()
     .and()
       .authorizeRequests() 
+        // PUBLIC SECTION
         .requestMatchers(PathRequest.toStaticResources().atCommonLocations()).permitAll()
+        .antMatchers("/").permitAll()
         .antMatchers(HttpMethod.POST, "/login").permitAll()
-        .antMatchers(HttpMethod.POST, "/user/signup").permitAll()
+        .antMatchers(HttpMethod.POST, "/users/signup").permitAll()
         .antMatchers(HttpMethod.GET, "/search").permitAll()
         .antMatchers(HttpMethod.GET, "/comments").permitAll()
+        .antMatchers(HttpMethod.GET, "/tags").permitAll()
         .antMatchers(HttpMethod.GET, "/models").permitAll()
-        .antMatchers(HttpMethod.GET, "/models/tags").permitAll()
         .antMatchers(HttpMethod.GET, "/models/download").permitAll()
-        .antMatchers(HttpMethod.GET, "/models/downloadLayer").permitAll()
-        // .anyRequest().authenticated()
+        .antMatchers(HttpMethod.GET, "/layers/download").permitAll()
+
+        // ADMIN SECTION
+        .antMatchers(HttpMethod.GET, "/models/setVerified").hasRole("ADMIN")
+        .antMatchers(HttpMethod.GET, "/users/setAdmin").hasRole("ADMIN")
+        .antMatchers(HttpMethod.DELETE, "/tags").hasRole("ADMIN")
+        .antMatchers(HttpMethod.DELETE, "/tags/category").hasRole("ADMIN")
+        .antMatchers(HttpMethod.POST, "/tags/category").hasRole("ADMIN")
+        .antMatchers(HttpMethod.GET, "/models/list").hasRole("ADMIN")
+        .antMatchers(HttpMethod.GET, "/users/list").hasRole("ADMIN")
+        .antMatchers(HttpMethod.GET, "/comments/list").hasRole("ADMIN")
+
+        // USER SECTION
+        .anyRequest().authenticated()
     .and()
       .addFilter(new JwtAuthenticationFilter(authenticationManager()))
       .addFilter(new JwtAuthorizationFilter(authenticationManager()))
diff --git a/mozen/src/main/java/mozen/business/IUserManager.java b/mozen/src/main/java/mozen/business/IUserManager.java
index 874ffbc..68ab588 100644
--- a/mozen/src/main/java/mozen/business/IUserManager.java
+++ b/mozen/src/main/java/mozen/business/IUserManager.java
@@ -7,13 +7,15 @@ import mozen.model.User;
 
 public interface IUserManager {
   User addUser(SignupMessage message);
-  void updateUser(User user, User userToUpdate);
+  void updateUser(User user, User userToUpdate) throws Exception;
   void removeUser(User user, Long id);
 
   Collection<User> getUsers();
   User getUser(Long id);
   User getUserByUsername(String username);
-  
+
+  void setAdmin(Long id, User user) throws Exception;
+
   boolean resetPassword(String email);
   boolean changePassword(String token, String password);
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/business/UserManager.java b/mozen/src/main/java/mozen/business/UserManager.java
index d2aac7f..c579f22 100644
--- a/mozen/src/main/java/mozen/business/UserManager.java
+++ b/mozen/src/main/java/mozen/business/UserManager.java
@@ -11,6 +11,7 @@ import mozen.model.Role;
 import mozen.messages.SignupMessage;
 import mozen.model.User;
 import mozen.repos.UserRepository;
+import mozen.utils.UserHelper;
 
 @Service
 public class UserManager implements IUserManager {
@@ -29,14 +30,14 @@ public class UserManager implements IUserManager {
     u.setEmail(message.getEmail());
     u.setUsername(message.getUsername());
     u.setPassword(bCryptPasswordEncoder.encode(message.getPassword()));
-    u.setRole(Role.ROLE_DEFAULT);
+    u.setRole(Role.DEFAULT);
 
     repo.save(u);
     return u;
   }
 
   @Override
-  public void updateUser(User user, User userToUpdate) {
+  public void updateUser(User user, User userToUpdate) throws Exception {
     if(isRightUser(user, userToUpdate)) repo.save(userToUpdate);
   }
 
@@ -76,8 +77,23 @@ public class UserManager implements IUserManager {
   }
 
   private boolean isRightUser(User userToCheck, User user) {
-    if (userToCheck.getRole() == Role.ROLE_ADMIN) return true;
+    if (userToCheck.getRole() == Role.ADMIN) return true;
     return userToCheck.getId().equals(user.getId());
   }
+
+  @Override
+  public void setAdmin(Long id, User user) throws Exception {
+    User userToUpdate = getUser(id);
+    if (userToUpdate == null)
+      throw new Exception("Unknown user");
+    if (!UserHelper.isAdmin(user))
+      throw new Exception("Not admin");
+
+    Role role = userToUpdate.getRole();
+    if (role == Role.ADMIN) userToUpdate.setRole(Role.DEFAULT);
+    else userToUpdate.setRole(Role.ADMIN);
+
+    repo.save(userToUpdate);
+  }
   
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/model/Role.java b/mozen/src/main/java/mozen/model/Role.java
index 1be603d..d6d617b 100644
--- a/mozen/src/main/java/mozen/model/Role.java
+++ b/mozen/src/main/java/mozen/model/Role.java
@@ -1,5 +1,5 @@
 package mozen.model;
 
 public enum Role {
-  ROLE_DEFAULT, ROLE_ADMIN
+  DEFAULT, ADMIN
 }
\ No newline at end of file
diff --git a/mozen/src/main/java/mozen/utils/DatabaseFiller.java b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
index ffe37fb..06c624a 100644
--- a/mozen/src/main/java/mozen/utils/DatabaseFiller.java
+++ b/mozen/src/main/java/mozen/utils/DatabaseFiller.java
@@ -48,19 +48,19 @@ public class DatabaseFiller {
     u1.setEmail("user1@email.com");
     u1.setPassword(bCryptPasswordEncoder.encode("1234"));
     u1.setUsername("user 1");
-    u1.setRole(Role.ROLE_DEFAULT);
+    u1.setRole(Role.DEFAULT);
 
     User u2 = new User();
     u2.setEmail("user2@email.com");
     u2.setPassword(bCryptPasswordEncoder.encode("1234"));
     u2.setUsername("user 2");
-    u2.setRole(Role.ROLE_DEFAULT);
+    u2.setRole(Role.DEFAULT);
 
     User admin = new User();
     admin.setEmail("admin@admin.admin");
     admin.setPassword(bCryptPasswordEncoder.encode("1234"));
     admin.setUsername("admin");
-    admin.setRole(Role.ROLE_ADMIN);
+    admin.setRole(Role.ADMIN);
 
     Model m1 = new Model();
     m1.setAuthor(u1);
diff --git a/mozen/src/main/java/mozen/utils/JwtUtils.java b/mozen/src/main/java/mozen/utils/JwtUtils.java
index 11c0136..3ada232 100644
--- a/mozen/src/main/java/mozen/utils/JwtUtils.java
+++ b/mozen/src/main/java/mozen/utils/JwtUtils.java
@@ -3,10 +3,13 @@ package mozen.utils;
 import java.security.Key;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
+import java.util.Collection;
 import java.util.Date;
 
 import javax.crypto.spec.SecretKeySpec;
 
+import org.springframework.security.core.GrantedAuthority;
+
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 
@@ -17,10 +20,12 @@ public class JwtUtils {
     return key;
   }
 
-  public static String generateToken(String username) {
+  public static String generateToken(String username, Collection<GrantedAuthority> roles) {
+    String role = roles.toArray()[0].toString();
     return Jwts.builder()
       .setSubject(username)
       .claim("username", username)
+      .claim("role", role)
       .setIssuedAt(new Date())
       .setExpiration(toDate(LocalDateTime.now().plusDays(1L)))
       .signWith(SignatureAlgorithm.HS512, generateKey())
diff --git a/mozen/src/main/java/mozen/utils/UserHelper.java b/mozen/src/main/java/mozen/utils/UserHelper.java
index 3054c20..8477802 100644
--- a/mozen/src/main/java/mozen/utils/UserHelper.java
+++ b/mozen/src/main/java/mozen/utils/UserHelper.java
@@ -17,7 +17,7 @@ public class UserHelper {
   }
 
   public static boolean isAdmin(User user) {
-    return user.getRole() == Role.ROLE_ADMIN;
+    return user.getRole() == Role.ADMIN;
   }
 
   public static User getCurrentUser(IUserManager userManager) {
diff --git a/mozen/src/main/java/mozen/web/UserController.java b/mozen/src/main/java/mozen/web/UserController.java
index 6d8978f..4a9f4d9 100644
--- a/mozen/src/main/java/mozen/web/UserController.java
+++ b/mozen/src/main/java/mozen/web/UserController.java
@@ -1,11 +1,15 @@
 package mozen.web;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 
 import javax.validation.Valid;
 
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.ResponseEntity;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.validation.BindingResult;
 import org.springframework.web.bind.annotation.CrossOrigin;
@@ -25,7 +29,7 @@ import mozen.utils.JwtUtils;
 import mozen.utils.UserHelper;
 
 @RestController
-@RequestMapping("/user")
+@RequestMapping("/users")
 @CrossOrigin
 public class UserController {
   @Autowired
@@ -87,8 +91,10 @@ public class UserController {
     ResponseMessage response = new ResponseMessage(false, "");
 
     try {
-      userManager.addUser(message);
-      response.setMessage(JwtUtils.generateToken(message.getUsername()));
+      User user = userManager.addUser(message);
+      Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
+      grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_"+user.getRole()));
+      response.setMessage(JwtUtils.generateToken(user.getUsername(), grantedAuthorities));
     } catch (Exception e) {
       response.setError(true);
       response.setMessage(e.getMessage());
@@ -97,4 +103,24 @@ public class UserController {
     return ResponseEntity.ok(response);
   }
 
+  @GetMapping("/setAdmin")
+  public ResponseEntity<ResponseMessage> setAdmin(@RequestParam(value = "id", required = true) Long id) {
+    ResponseMessage response = new ResponseMessage(false, "");
+    User user = UserHelper.getCurrentUser(userManager);
+    if(user == null) {
+      response.setError(true);
+      response.setMessage("User unknown");
+      return ResponseEntity.badRequest().body(response);
+    }
+
+    try {
+      userManager.setAdmin(id, user);
+    } catch (Exception e) {
+      response.setError(true);
+      response.setMessage(e.getMessage());
+      return ResponseEntity.badRequest().body(response);
+    }
+
+    return ResponseEntity.ok(response);
+  }
 }
\ No newline at end of file
-- 
GitLab