Projekt

Obecné

Profil

Stáhnout (7.95 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
        if (userRepository.findByEmail(userDto.getEmail()).isPresent()) {
70
            log.error("Trying to register new user with username that is already taken: " + userDto.getEmail());
71
            throw new ApiRequestException(String.format("User with username %s already exists", userDto.getEmail()), HttpStatus.CONFLICT);
72
        }
73
        UserEntity userEntity = new UserEntity();
74
        convertDtoToEntity(userDto, userEntity);
75
        userRepository.save(userEntity);
76
    }
77

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

    
92
    @Override
93
    public void resetPassword(String username, String newPassword) {
94
        if (username.equals(SUPER_ADMIN_NAME)) {
95
            log.error("Password for SUPER ADMIN can not be changed");
96
            throw new ApiRequestException("Password for SUPER ADMIN can not be changed", HttpStatus.BAD_REQUEST);
97
        }
98
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
99
            log.error(String.format(USER_NOT_FOUND, username));
100
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
101
        });
102
        userEntity.setPassword(bCryptPasswordEncoder.encode(newPassword));
103
        userRepository.save(userEntity);
104
    }
105

    
106
    @Override
107
    public void deleteUser(String username) {
108
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
109
            log.error(String.format(USER_NOT_FOUND, username));
110
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
111
        });
112
        if (userEntity.isAdmin()) {
113
            log.error("User with ADMIN rights can not be deleted");
114
            throw new ApiRequestException("User with ADMIN rights can not be deleted", HttpStatus.BAD_REQUEST);
115
        }
116
        userRepository.delete(userEntity);
117
    }
118

    
119
    @Override
120
    public List<UserDto> getAllUsers() {
121
        return userRepository.findAll().stream().filter(u -> !u.getEmail().equals(SUPER_ADMIN_NAME)).map(this::convertEntityToDto).collect(Collectors.toList());
122
    }
123

    
124
    @Override
125
    public void changePassword(String oldPassword, String newPassword) {
126
        UserEntity loggedUser = getUserByName((String) SecurityContextHolder.getContext().getAuthentication().getPrincipal());
127
        if (loggedUser.getEmail().equals(SUPER_ADMIN_NAME)) {
128
            throw new ApiRequestException("Can not change password for SUPER ADMIN", HttpStatus.BAD_REQUEST);
129
        }
130
        if (!bCryptPasswordEncoder.matches(oldPassword, loggedUser.getPassword())) {
131
            throw new ApiRequestException("Old password does not match", HttpStatus.BAD_REQUEST);
132
        }
133
        loggedUser.setPassword(bCryptPasswordEncoder.encode(newPassword));
134
        userRepository.save(loggedUser);
135
    }
136

    
137

    
138
    /**
139
     * Converts user DTO to user entity
140
     *
141
     * @param userDto    user DTO
142
     * @param userEntity user entity
143
     */
144
    private void convertDtoToEntity(UserDto userDto, UserEntity userEntity) {
145
        userEntity.setName(userDto.getName());
146
        userEntity.setEmail(userDto.getEmail());
147
        userEntity.setPermissions(getPermissionsFromDto(userDto.getPermissions()));
148
        userEntity.setPassword(bCryptPasswordEncoder.encode(userDto.getPasswords().getPassword()));
149
    }
150

    
151
    /**
152
     * Converts user entity to user DTO
153
     *
154
     * @param userEntity user entity
155
     * @return user DTO from user entity
156
     */
157
    private UserDto convertEntityToDto(UserEntity userEntity) {
158
        UserDto userDto = new UserDto();
159
        userDto.setName(userEntity.getName());
160
        userDto.setEmail(userEntity.getEmail());
161
        setPermissionsToDto(userDto, userEntity);
162
        return userDto;
163
    }
164

    
165
    /**
166
     * Sets permission to user DTO based on user entity
167
     *
168
     * @param userDto    user DTO
169
     * @param userEntity user entity
170
     */
171
    private void setPermissionsToDto(UserDto userDto, UserEntity userEntity) {
172
        byte userPermissions = userEntity.getPermissions();
173
        PermissionDto permissionDto = new PermissionDto();
174
        if ((userPermissions & Permission.READ.getBit()) == Permission.READ.getBit()) {
175
            permissionDto.setCanRead(true);
176
        }
177
        if ((userPermissions & Permission.WRITE.getBit()) == Permission.WRITE.getBit()) {
178
            permissionDto.setCanWrite(true);
179
        }
180
        if ((userPermissions & Permission.DELETE.getBit()) == Permission.DELETE.getBit()) {
181
            permissionDto.setCanDelete(true);
182
        }
183
        userDto.setPermissions(permissionDto);
184
    }
185

    
186
    /**
187
     * Returns permissions as byte from permission DTO
188
     *
189
     * @param permissionDto permission DTO
190
     * @return permissions as byte
191
     */
192
    private byte getPermissionsFromDto(PermissionDto permissionDto) {
193
        byte permissions = (byte) 0;
194
        if (permissionDto.isCanRead()) {
195
            permissions |= Permission.READ.getBit();
196
        }
197
        if (permissionDto.isCanWrite()) {
198
            permissions |= Permission.WRITE.getBit();
199
        }
200
        if (permissionDto.isCanDelete()) {
201
            permissions |= Permission.DELETE.getBit();
202
        }
203
        return permissions;
204
    }
205
}
(7-7/7)