简体   繁体   中英

How can I filter out a get request of all users in my DB so that users with an admin role are not shown in the list?

I am building a spring boot application that allows an admin to view a list of all users saved in my Database. However, at the moment, all users including the ones with an admin role are being displayed. I was suggested to filter out admins in the backend code but I am not sure how to go about doing this. If anyone could help me, it would very much appreciated. Thank you! (I am using JPA + Hibernate)

UPDATE: I was suggested a solution that was very useful below. I needed to make a getUsers method which queries data from my Database in a way that filters out admins. At first, I was having issues with the SQL part of the query since I am using hibernate (I think, correct me if I am wrong). I was made aware that you can't use a JPQL query to access raw entity data from tables, since I was using @JoinTable to create my user_roles table that doesn't have an entity class for it, I was confused. Seen in my User class as follows:

 @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set<Role> roles = new HashSet<>();

I was receiving a red line in my user repository class at user_role ur in FROM User u,Role r, user_role ur . Futhermore, I was receiving the following error: user_role is not mapped [SELECT u.id,u.username,u.email FROM com.Application.models.User u,com.Application.models.Role r, user_role ur WHERE u.id=ur.id AND r.id=ur.id AND r.name<>'ADMIN'] . My Role entity is used to map the role ID and the role name whereas my user_role table contains a column of the user ID and the role ID in one table for mapping the user id to a role id. That is where my last error was.

My Solution :

 @Query("SELECT u FROM User u join u.roles r WHERE NOT EXISTS" + "(SELECT r FROM u.roles WHERE r.name = 'ROLE_ADMIN')") List<User> getUsers();

This succesfuly filtered out users with an admin role in my case. I hope this helps someone one day, I was stuck on this for a minute. Thanks for all the help!

User.java:

 package com.Application.models; import javax.persistence.*; import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; import javax.validation.constraints.Size; import java.util.HashSet; import java.util.Set; @Entity @Table( name = "users", uniqueConstraints = { @UniqueConstraint(columnNames = "username"), }) public class User { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "username") @NotBlank @Size(max = 20) private String username; @Column(name = "email") @NotBlank @Size(max = 50) @Email private String email; @NotBlank @Size(max = 120) private String password; @ManyToMany(fetch = FetchType.LAZY) @JoinTable( name = "user_roles", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) private Set<Role> roles = new HashSet<>(); @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user") private Set<UserPost> userPosts = new HashSet<>(); public User(String username, String email,String password) { this.username = username; this.email = email; this.password = password; } public User() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } }

TestController.java:

 package com.Application.controller; import com.Application.models.User; import com.Application.repository.UserPostsRepository; import com.Application.repository.UserProfileRepository; import com.Application.repository.UserRepository; import com.Application.security.jwt.JwtUtils; import com.Application.security.services.UserDetailsService; import com.Application.security.services.UserPostService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @CrossOrigin(origins = "http://localhost:3000") @RestController @RequestMapping("/api/test") public class TestController { private static final String AUTH_HEADER = "authorization"; @Autowired private final UserPostsRepository userPostRepo; @Autowired private final UserRepository userRepo; @Autowired private final UserProfileRepository userProfRepo; @Autowired private UserDetailsService userDetailsService; @Autowired private UserPostService userPostService; @Autowired JwtUtils jwtUtils; public TestController(UserPostsRepository userPostRepo, UserRepository userRepo, UserProfileRepository userProfRepo) { this.userPostRepo = userPostRepo; this.userRepo = userRepo; this.userProfRepo = userProfRepo; } @GetMapping("/all") public String allAccess() { return "Public Content."; } @GetMapping("/user") @PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')") public String userAccess() { return "User Content."; } @GetMapping("/mod") @PreAuthorize("hasRole('MODERATOR')") public String moderatorAccess() { return "Moderator Board."; } @GetMapping("/admin") @PreAuthorize("hasRole('ADMIN')") public List<User> adminAccess(Model model) { List<User> allUsers = userRepo.getUsers(); allUsers.forEach(user -> model.addAttribute("username", user.getUsername())); return allUsers; } }

Role.java:

 package com.Application.models; import javax.persistence.*; @Entity @Table(name = "roles") public class Role { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Enumerated(EnumType.STRING) @Column(length = 20) private ERole name; public Role() { } public Role(ERole name) { this.name = name; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public ERole getName() { return name; } public void setName(ERole name) { this.name = name; } }

ERole.java:

 package com.Application.models; public enum ERole { ROLE_USER, ROLE_MODERATOR, ROLE_ADMIN }

UserRepository.java:

 package com.Application.repository; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import com.Application.models.User; @Repository public interface UserRepository extends JpaRepository<User, Long> { Optional<User> findByUsername(String username); User findUserById(Long id); Optional<User> findByEmail(String email); List<User> findAll(); @Query("SELECT u.id,u.username,u.email FROM User u,Role r, user_role ur WHERE u.id=ur.id AND r.id=ur.id AND r.name<>\'ADMIN\'") //Error at users u, roles r, user_roles ur even though the table names are right List<User> getUsers(); Boolean existsByUsername(String username); Boolean existsByEmail(String email);

RoleRepository.java:

 package com.Application.repository; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.Application.models.ERole; import com.Application.models.Role; @Repository public interface RoleRepository extends JpaRepository<Role, Long> { Optional<Role> findByName(ERole name); }

There are better ways to do this but here is a simple way.Just add the below method in your repository interface

@Query("SELECT u.firstname,u.lastname,u.email FROM user u,role r,user_role ur WHERE u.id=ur.user_id AND r.id=ur.role_id AND r.name<>\'ADMIN\'")
List<User> getUsers();

getUsers() retuns a list of users except admin users. Of course you can change the query depending on what columns are in user table and change user_roles with the name of the appropriate table in your database.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM