lundi 24 mai 2021

SpringBoot edit user's roles list

I am using spring security to secure an application , i have User and Role entities , a user can have multiple roles , i can add a new user with multiples roles with success, but for editing a user if he have one role then it's checked , if he have more than one role then no checkbox is checked at all.

User.java

@Entity(name = "user")
@Table(name = "users")
@PasswordValueMatch.List({
    @PasswordValueMatch(field = "password", fieldMatch = "matchingPassword", message = 
"Passwords do not match!") })

public class User {

@Id
@Column(name = "user_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@NotNull
@NotEmpty
private String username;

@NotNull
@NotEmpty
private String first_name;

@NotNull
@NotEmpty
private String last_name;

@ValidEmail
@NotNull
@NotEmpty
private String email;

@NotNull
@ValidPassword
private String password;

private boolean enabled;

@NotNull
@Transient
@ValidPassword
private String matchingPassword;

@ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
@JoinTable(name = "users_roles", joinColumns = @JoinColumn(name = "user_id"), 

inverseJoinColumns = @JoinColumn(name = "role_id")) private Set roles = new HashSet<>();

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 getFirst_name() {
    return first_name;
}

public void setFirst_name(String first_name) {
    this.first_name = first_name;
}

public String getLast_name() {
    return last_name;
}

public void setLast_name(String last_name) {
    this.last_name = last_name;
}

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 boolean isEnabled() {
    return enabled;
}

public void setEnabled(boolean enabled) {
    this.enabled = enabled;
}

public Set<Role> getRoles() {
    return roles;
}

public void setRoles(Set<Role> roles) {
    this.roles = roles;
}

public String getMatchingPassword() {
    return matchingPassword;
}

public void setMatchingPassword(String matchingPassword) {
    this.matchingPassword = matchingPassword;
}
}

Role.java

@Entity
@Table(name = "roles")
public class Role {

@Id
@Column(name = "role_id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
 
private String name;

public Integer getId() {
    return id;
}

public void setId(Integer id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public String toString() {
    return "Role [id=" + id + ", name=" + name + "]";
}   
}

User controller sample :

@RequestMapping("/manage/edit/{id}")
public ModelAndView showEditUser(@PathVariable(name = "id") int id) {
    ModelAndView mav = new ModelAndView("edit_user");
    Optional<User>  user = userService.findUser(new Long(id));
    mav.addObject("user", user);
    
    List<Role> roles = initializeRoles();
    
    mav.addObject("allRoles", roles);
     
    return mav;
}
public List<Role> initializeRoles(){
    List<Role> roles = roleRepository.findAll();

    return roles ;
}

edit_user.html :

<form th:action="@{/manage/doRegistration}" th:object="${user}"
                                method="POST" enctype="utf8">

                                <div class="row justify-content-center">
                                    <span class="alert alert-danger" th:if="${errorMessage}"
                                        th:text="${errorMessage}">Error</span>
                                </div>

                                <div class="input-group mb-3">
                                    <input type="text" class="form-control"
                                        th:field="*{first_name}" placeholder="First Name"
                                        th:errorclass="is-invalid" required="required" />
                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-user"></span>
                                        </div>
                                    </div>
                                    <div class="alert alert-danger"
                                        th:if="${#fields.hasErrors('enabled')}"
                                        th:errors="*{first_name}"></div>
                                </div>
                                <div class="input-group mb-3">
                                    <input type="text" class="form-control"
                                        th:field="*{last_name}" placeholder="Last Name"
                                        th:errorclass="is-invalid" required="required" />
                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-user"></span>
                                        </div>
                                    </div>
                                    <div class="alert alert-danger"
                                        th:if="${#fields.hasErrors('last_name')}"
                                        th:errors="*{last_name}"></div>
                                </div>
                                <div class="input-group mb-3">
                                    <input type="text" class="form-control" th:field="*{username}"
                                        placeholder="Login" th:errorclass="is-invalid"
                                        required="required" />
                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-user"></span>
                                        </div>
                                    </div>
                                    <div class="alert alert-danger"
                                        th:if="${#fields.hasErrors('username')}"
                                        th:errors="*{username}"></div>
                                </div>
                                <div class="input-group mb-3">
                                    <input type="email" class="form-control" th:field="*{email}"
                                        placeholder="Email" th:errorclass="is-invalid"
                                        required="required" />
                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-envelope"></span>
                                        </div>
                                    </div>
                                    <div class="alert alert-danger"
                                        th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div>
                                </div>
                                <div class="input-group mb-3">
                                    <input type="password" class="form-control"
                                        th:field="*{password}" placeholder="Password"
                                        th:errorclass="is-invalid" required="required" />

                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-lock"></span>
                                        </div>
                                    </div>
                                </div>
                                <div class="alert alert-danger"
                                    th:if="${#fields.hasErrors('password')}"
                                    th:errors="*{password}"></div>


                                <div class="input-group mb-3">
                                    <input type="password" class="form-control"
                                        th:field="*{matchingPassword}" placeholder="Confirm Password"
                                        th:errorclass="is-invalid" required="required" />
                                    <div class="input-group-append">
                                        <div class="input-group-text">
                                            <span class="fas fa-lock"></span>
                                        </div>
                                    </div>
                                </div>


                                Roles :

                                <div class="input-group mb-3">
                                    <th:block th:each="role : ${allRoles}">
                                        <div class="custom-control custom-control-inline">
                                            <input type="checkbox" class="custom-control-input"
                                                th:value="${role.id}" th:field="*{roles}"> <label
                                                class="custom-control-label" th:for="${role.id}"
                                                th:text="${role.name}">Business</label>
                                        </div>
                                    </th:block>
                                </div>


                                <div class="input-group mb-3">
                                <div class="custom-control custom-control-inline">
                                        <input type="checkbox" class="custom-control-input"
                                            th:field="*{enabled}" th:id="check"/>
                                    <label class="custom-control-label" th:for="check" th:id="lbl">Enabled</label>
                                            
                                </div>
                                </div>


                                <div class="d-flex justify-content-between">
                                    <div></div>
                                    <div>
                                        <button type="submit" class="btn btn-primary btn-block">Edit</button>
                                    </div>
                                </div>
                            </form>

NB : this code above is rendering all roles but if the user has one role it's checked , if the user has more than one , no role is checked at all .




Aucun commentaire:

Enregistrer un commentaire