Projekt

Obecné

Profil

Stáhnout (8.48 KB) Statistiky
| Větev: | Tag: | Revize:
1
package cz.zcu.kiv.backendapi.user;
2

    
3
import cz.zcu.kiv.backendapi.exception.ApiRequestException;
4
import cz.zcu.kiv.backendapi.user.permission.Permission;
5
import cz.zcu.kiv.backendapi.user.permission.PermissionDto;
6
import lombok.RequiredArgsConstructor;
7
import lombok.extern.slf4j.Slf4j;
8
import org.springframework.http.HttpStatus;
9
import org.springframework.security.core.context.SecurityContextHolder;
10
import org.springframework.security.core.userdetails.UserDetails;
11
import org.springframework.security.core.userdetails.UserDetailsService;
12
import org.springframework.security.core.userdetails.UsernameNotFoundException;
13
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
14
import org.springframework.stereotype.Service;
15
import org.springframework.transaction.annotation.Transactional;
16

    
17
import java.util.List;
18
import java.util.stream.Collectors;
19

    
20
/**
21
 * User service implementation
22
 */
23
@Service
24
@Transactional
25
@RequiredArgsConstructor
26
@Slf4j
27
public class UserServiceImpl implements IUserService, UserDetailsService {
28
    /**
29
     * Super ADMIN name
30
     */
31
    private static final String SUPER_ADMIN_NAME = "admin@admin.com";
32

    
33
    /**
34
     * Message for exception when user is not found by username
35
     */
36
    private static final String USER_NOT_FOUND = "User with username %s not found";
37

    
38
    /**
39
     * User repository
40
     */
41
    private final UserRepository userRepository;
42

    
43
    /**
44
     * Password encoder
45
     */
46
    private final BCryptPasswordEncoder bCryptPasswordEncoder;
47

    
48

    
49
    @Override
50
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
51
        return userRepository.findByEmail(username)
52
                .orElseThrow(() -> {
53
                    log.error(String.format(USER_NOT_FOUND, username));
54
                    throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
55
                });
56
    }
57

    
58
    @Override
59
    public UserEntity getUserByName(String username) {
60
        return userRepository.findByEmail(username).
61
                orElseThrow(() -> {
62
                    log.error(String.format(USER_NOT_FOUND, username));
63
                    throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
64
                });
65
    }
66

    
67
    @Override
68
    public void registerNewUser(UserDto userDto) {
69
        log.info("Registering new user");
70
        if (userRepository.findByEmail(userDto.getEmail()).isPresent()) {
71
            log.error("Trying to register new user with username that is already taken: " + userDto.getEmail());
72
            throw new ApiRequestException(String.format("User with username %s already exists", userDto.getEmail()), HttpStatus.CONFLICT);
73
        }
74
        UserEntity userEntity = new UserEntity();
75
        convertDtoToEntity(userDto, userEntity);
76
        userRepository.save(userEntity);
77
        log.info("New user registered");
78
    }
79

    
80
    @Override
81
    public void updatePermissions(String username, PermissionDto permissionDto) {
82
        log.info("Updating permissions to user: " + username);
83
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
84
            log.error(String.format(USER_NOT_FOUND, username));
85
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
86
        });
87
        if (userEntity.isAdmin()) {
88
            log.error("Permissions for user with ADMIN rights can not be changed");
89
            throw new ApiRequestException("Permissions for user with ADMIN rights can not be changed", HttpStatus.BAD_REQUEST);
90
        }
91
        userEntity.setPermissions(getPermissionsFromDto(permissionDto));
92
        userRepository.save(userEntity);
93
        log.info("Permissions to user " + username + " updated");
94
    }
95

    
96
    @Override
97
    public void resetPassword(String username, String newPassword) {
98
        log.info("Resetting password to user " + username);
99
        if (username.equals(SUPER_ADMIN_NAME)) {
100
            log.error("Password for SUPER ADMIN can not be changed");
101
            throw new ApiRequestException("Password for SUPER ADMIN can not be changed", HttpStatus.BAD_REQUEST);
102
        }
103
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
104
            log.error(String.format(USER_NOT_FOUND, username));
105
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
106
        });
107
        userEntity.setPassword(bCryptPasswordEncoder.encode(newPassword));
108
        userRepository.save(userEntity);
109
        log.info("Password to user " + username + " reset");
110
    }
111

    
112
    @Override
113
    public void deleteUser(String username) {
114
        log.info("Deleting user " + username);
115
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
116
            log.error(String.format(USER_NOT_FOUND, username));
117
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
118
        });
119
        if (userEntity.isAdmin()) {
120
            log.error("User with ADMIN rights can not be deleted");
121
            throw new ApiRequestException("User with ADMIN rights can not be deleted", HttpStatus.BAD_REQUEST);
122
        }
123
        userRepository.delete(userEntity);
124
        log.info("User " + username + " deleted");
125
    }
126

    
127
    @Override
128
    public List<UserDto> getAllUsers() {
129
        return userRepository.findAll().stream().filter(u -> !u.getEmail().equals(SUPER_ADMIN_NAME)).map(this::convertEntityToDto).collect(Collectors.toList());
130
    }
131

    
132
    @Override
133
    public void changePassword(String oldPassword, String newPassword) {
134
        log.info("Changing password to logged user");
135
        UserEntity loggedUser = getUserByName((String) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
136
        if (loggedUser.getEmail().equals(SUPER_ADMIN_NAME)) {
137
            throw new ApiRequestException("Can not change password for SUPER ADMIN", HttpStatus.BAD_REQUEST);
138
        }
139
        if (!bCryptPasswordEncoder.matches(oldPassword, loggedUser.getPassword())) {
140
            throw new ApiRequestException("Old password does not match", HttpStatus.BAD_REQUEST);
141
        }
142
        loggedUser.setPassword(bCryptPasswordEncoder.encode(newPassword));
143
        userRepository.save(loggedUser);
144
        log.info("Password to logged user changed");
145
    }
146

    
147

    
148
    /**
149
     * Converts user DTO to user entity
150
     *
151
     * @param userDto    user DTO
152
     * @param userEntity user entity
153
     */
154
    private void convertDtoToEntity(UserDto userDto, UserEntity userEntity) {
155
        userEntity.setName(userDto.getName());
156
        userEntity.setEmail(userDto.getEmail());
157
        userEntity.setPermissions(getPermissionsFromDto(userDto.getPermissions()));
158
        userEntity.setPassword(bCryptPasswordEncoder.encode(userDto.getPasswords().getPassword()));
159
    }
160

    
161
    /**
162
     * Converts user entity to user DTO
163
     *
164
     * @param userEntity user entity
165
     * @return user DTO from user entity
166
     */
167
    private UserDto convertEntityToDto(UserEntity userEntity) {
168
        UserDto userDto = new UserDto();
169
        userDto.setName(userEntity.getName());
170
        userDto.setEmail(userEntity.getEmail());
171
        setPermissionsToDto(userDto, userEntity);
172
        return userDto;
173
    }
174

    
175
    /**
176
     * Sets permission to user DTO based on user entity
177
     *
178
     * @param userDto    user DTO
179
     * @param userEntity user entity
180
     */
181
    private void setPermissionsToDto(UserDto userDto, UserEntity userEntity) {
182
        byte userPermissions = userEntity.getPermissions();
183
        PermissionDto permissionDto = new PermissionDto();
184
        if ((userPermissions & Permission.READ.getBit()) == Permission.READ.getBit()) {
185
            permissionDto.setCanRead(true);
186
        }
187
        if ((userPermissions & Permission.WRITE.getBit()) == Permission.WRITE.getBit()) {
188
            permissionDto.setCanWrite(true);
189
        }
190
        if ((userPermissions & Permission.DELETE.getBit()) == Permission.DELETE.getBit()) {
191
            permissionDto.setCanDelete(true);
192
        }
193
        userDto.setPermissions(permissionDto);
194
    }
195

    
196
    /**
197
     * Returns permissions as byte from permission DTO
198
     *
199
     * @param permissionDto permission DTO
200
     * @return permissions as byte
201
     */
202
    private byte getPermissionsFromDto(PermissionDto permissionDto) {
203
        byte permissions = (byte) 0;
204
        if (permissionDto.isCanRead()) {
205
            permissions |= Permission.READ.getBit();
206
        }
207
        if (permissionDto.isCanWrite()) {
208
            permissions |= Permission.WRITE.getBit();
209
        }
210
        if (permissionDto.isCanDelete()) {
211
            permissions |= Permission.DELETE.getBit();
212
        }
213
        return permissions;
214
    }
215
}
(7-7/7)