Projekt

Obecné

Profil

Stáhnout (8.02 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
    //TODO maybe check if user is not deleting himself - or it might be ok
107
    @Override
108
    public void deleteUser(String username) {
109
        UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> {
110
            log.error(String.format(USER_NOT_FOUND, username));
111
            throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username));
112
        });
113
        if (userEntity.isAdmin()) {
114
            log.error("User with ADMIN rights can not be deleted");
115
            throw new ApiRequestException("User with ADMIN rights can not be deleted", HttpStatus.BAD_REQUEST);
116
        }
117
        userRepository.delete(userEntity);
118
    }
119

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

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

    
138

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

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

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

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