Индивидуальный метод на уровне модели - PullRequest
0 голосов
/ 25 марта 2019

Я разработал сервис аутентификации с использованием Spring Cloud Architecture. Мне нужны все права пользователя в классе PrincipleController, и поэтому я реализовал пользовательский метод в классе сущностей пользователей. Существуют отношения между объектами User-Role, User-Permission и Role-Permission. Я хочу знать, что реализация пользовательского (после getAllPermissions ()) метода в классе сущности (я имею в виду реализацию уровня модели) является плохой практикой или нет?

package x.y.z.backend.auth.controller;

import x.y.z.backend.auth.model.*;
import x.y.z.backend.auth.service.PermissionService;
import x.y.z.backend.auth.service.PrincipalService;
import x.y.z.backend.auth.service.RoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.security.Principal;
import java.util.Set;

@RestController
@RequestMapping("/me")
public class PrincipalController {
    public static final Logger LOG = LoggerFactory.getLogger(PrincipalController.class);

    private RoleService roleService;
    private PermissionService permissionService;
    private PrincipalService principalService;

    @Autowired
    public PrincipalController(RoleService roleService, PermissionService permissionService, PrincipalService principalService) {
        this.roleService = roleService;
        this.permissionService = permissionService;
        this.principalService = principalService;
    }

    public PrincipalController() {
    }

    @GetMapping
    public CustomPrincipal principal(Principal principal) {
        User user = principalService.findByEmail(principal.getName()).get();
        Set<Permission> permissions =  user.getAllPermissions();
        OAuth2Authentication auth = (OAuth2Authentication) principal;
        CustomPrincipal customPrincipal = new CustomPrincipal(user.getFirstName(), user.getLastName(), principal.getName(),
                auth.getOAuth2Request(), auth.getUserAuthentication(), auth.getAuthorities(), auth.getDetails(), auth.isAuthenticated(),
                auth.isClientOnly(), permissions, user.getTenant().getTenantName());
        return customPrincipal;
    }

    @PutMapping
    public User update(@Valid @RequestBody User user, BindingResult bindingResult, Principal principal) {
        return principalService.update(user, bindingResult, principal);
    }

    @PutMapping(path = "/change_password")
    public User updatePassword(@Valid @RequestBody UserPassword userPassword, BindingResult bindingResult, Principal principal) {
        return principalService.updatePassword(userPassword, bindingResult, principal);
    }

    @GetMapping(path = "/roles")
    public Set<Role> getRoles(Principal principal) {
        String username = principal.getName();
        return roleService.findByEmail(username);
    }

    @GetMapping(path = "/permissions")
    public Set<Permission> getPermissions(Principal principal) {
        String username = principal.getName();
        return permissionService.findByEmail(username);
    }
}




package x.y.z.backend.auth.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityCoreVersion;
import org.springframework.security.core.userdetails.UserDetails;

import javax.persistence.*;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import static x.y.z.backend.auth.enums.Parameter.TENANT_SCHEMA_NAME;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(exclude = {"roles", "permissions", "tenant"})
@ToString(exclude = {"roles", "permissions", "tenant"})
@Entity(name = "users")
@Table(schema = TENANT_SCHEMA_NAME)
public class User implements UserDetails {
    @Transient
    private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull(message = "First name could not be empty")
    @Size(min = 2, max = 20, message = "First name must be between {min} and {max} characters long")
    private String firstName;

    @NotNull(message = "Last name could not be empty")
    @Size(min = 2, max = 20, message = "Last name must be between {min} and {max} characters long")
    private String lastName;

    @Email(message = "Invalid e-mail address")
    @NotNull(message = "E-mail could not be empty")
    @Column(unique = true, nullable = false)
    @Size(min = 5, max = 100, message = "E-mail must be between {min} and {max} characters long")
    private String email;

    @Getter(onMethod = @__(@JsonIgnore))
    @Setter(onMethod = @__(@JsonProperty("password")))
    @Column(length = 60)
    private String password;

    @NotNull
    private boolean accountNonExpired;

    @NotNull
    private boolean accountNonLocked;

    @NotNull
    private boolean credentialsNonExpired;

    @NotNull
    private boolean enabled;

    @Column(nullable = false)
    private LocalDateTime createdAt;

    private LocalDateTime updatedAt;

    private LocalDateTime deletedAt;

    @Getter(onMethod = @__(@JsonIgnore))
    @Setter(onMethod = @__(@JsonProperty("roles")))
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(schema = TENANT_SCHEMA_NAME, name = "user_roles", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "role_id", referencedColumnName = "id"))
    private Set<Role> roles = new HashSet<>(0);

    @Getter(onMethod = @__(@JsonIgnore))
    @Setter(onMethod = @__(@JsonProperty("permissions")))
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(schema = TENANT_SCHEMA_NAME, name = "user_permissions", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "permission_id", referencedColumnName = "id"))
    private Set<Permission> permissions = new HashSet<>(0);

    @Getter(onMethod = @__(@JsonIgnore))
    @Setter(onMethod = @__(@JsonProperty("tenant")))
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinTable(schema = TENANT_SCHEMA_NAME, name = "tenant_users", joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "tenant_id", referencedColumnName = "id"))
    private Tenant tenant;

    public User(String firstName, String lastName, String email, String password, boolean accountNonExpired,
                boolean accountNonLocked, boolean credentialsNonExpired, boolean enabled,
                LocalDateTime createdAt, LocalDateTime updatedAt, LocalDateTime deletedAt, Set<Role> roles) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
        this.password = password;
        this.accountNonExpired = accountNonExpired;
        this.accountNonLocked = accountNonLocked;
        this.credentialsNonExpired = credentialsNonExpired;
        this.enabled = enabled;
        this.createdAt = createdAt;
        this.updatedAt = updatedAt;
        this.deletedAt = deletedAt;
        this.roles = roles;
    }

    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        grantedAuthorities.addAll(roles);
        grantedAuthorities.addAll(permissions);
        return grantedAuthorities;
    }

    public Set<Permission> getAllPermissions() {
        Set<Permission> allPermissions = new HashSet<>();
        allPermissions.addAll(this.permissions);
        this.roles.forEach(role -> allPermissions.addAll(role.getPermissions()));
        return allPermissions;
    }

    @Override
    public String getUsername() {
        return this.getEmail();
    }
}
...