Revize a86d66a4
Přidáno uživatelem Jakub Šmíd před téměř 3 roky(ů)
backend/src/main/java/cz/zcu/kiv/backendapi/config/DataInitiator.java | ||
---|---|---|
66 | 66 |
UserEntity user2 = new UserEntity("normal", "normal", encoder.encode("password"), (byte) 1, false); |
67 | 67 |
userRepository.save(user2); |
68 | 68 |
|
69 |
UserEntity superAmin = new UserEntity("SuperAdmin", "admin@admin.com", "$2a$10$WN7iAmrlUZiHMShI85.ScOyBbGXMMondhh.7x/WopeQ8YIMVyA8O2", (byte) 7, true); |
|
70 |
userRepository.save(superAmin); |
|
71 |
|
|
69 | 72 |
} |
70 | 73 |
|
71 | 74 |
private List<CatalogItem> loadCatalog() { |
backend/src/main/java/cz/zcu/kiv/backendapi/user/UserEntity.java | ||
---|---|---|
30 | 30 |
private String name; |
31 | 31 |
|
32 | 32 |
/** |
33 |
* Email - serves as username and must be unique - serves as Id
|
|
33 |
* Email - serves as username and must be unique - serves as ID
|
|
34 | 34 |
*/ |
35 | 35 |
@Id |
36 | 36 |
private String email; |
backend/src/main/java/cz/zcu/kiv/backendapi/user/UserServiceImpl.java | ||
---|---|---|
25 | 25 |
@RequiredArgsConstructor |
26 | 26 |
@Slf4j |
27 | 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 |
|
|
28 | 33 |
/** |
29 | 34 |
* Message for exception when user is not found by username |
30 | 35 |
*/ |
... | ... | |
76 | 81 |
log.error(String.format(USER_NOT_FOUND, username)); |
77 | 82 |
throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username)); |
78 | 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 |
} |
|
79 | 88 |
userEntity.setPermissions(getPermissionsFromDto(permissionDto)); |
80 | 89 |
userRepository.save(userEntity); |
81 | 90 |
} |
82 | 91 |
|
83 | 92 |
@Override |
84 | 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 |
} |
|
85 | 98 |
UserEntity userEntity = userRepository.findByEmail(username).orElseThrow(() -> { |
86 | 99 |
log.error(String.format(USER_NOT_FOUND, username)); |
87 | 100 |
throw new UsernameNotFoundException(String.format(USER_NOT_FOUND, username)); |
... | ... | |
106 | 119 |
|
107 | 120 |
@Override |
108 | 121 |
public List<UserDto> getAllUsers() { |
109 |
return userRepository.findAll().stream().map(this::convertEntityToDto).collect(Collectors.toList()); |
|
122 |
return userRepository.findAll().stream().filter(u -> !u.getEmail().equals(SUPER_ADMIN_NAME)).map(this::convertEntityToDto).collect(Collectors.toList());
|
|
110 | 123 |
} |
111 | 124 |
|
112 | 125 |
@Override |
113 | 126 |
public void changePassword(String oldPassword, String newPassword) { |
114 | 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 |
} |
|
115 | 131 |
if (!bCryptPasswordEncoder.matches(oldPassword, loggedUser.getPassword())) { |
116 | 132 |
throw new ApiRequestException("Old password does not match", HttpStatus.BAD_REQUEST); |
117 | 133 |
} |
backend/src/test/java/cz/zcu/kiv/backendapi/user/UserServiceImplTest.java | ||
---|---|---|
177 | 177 |
verify(userRepository, never()).save(any()); |
178 | 178 |
} |
179 | 179 |
|
180 |
@Test |
|
181 |
void testCanNotUpdatePermissionsAdmin() { |
|
182 |
// given |
|
183 |
String email = "test@test.com"; |
|
184 |
UserEntity userEntity = new UserEntity("John Doe", email, "", (byte) 0, true); |
|
185 |
PermissionDto permissionDto = new PermissionDto(); |
|
186 |
given(userRepository.findByEmail(email)).willReturn(Optional.of(userEntity)); |
|
187 |
|
|
188 |
// when |
|
189 |
assertThatThrownBy(() -> underTest.updatePermissions(email, permissionDto)) |
|
190 |
.isInstanceOf(ApiRequestException.class) |
|
191 |
.hasMessageContaining("Permissions for user with ADMIN rights can not be changed"); |
|
192 |
|
|
193 |
// then |
|
194 |
verify(userRepository, never()).delete(any()); |
|
195 |
} |
|
196 |
|
|
180 | 197 |
@Test |
181 | 198 |
void testCanResetPassword() { |
182 | 199 |
// given |
... | ... | |
216 | 233 |
verify(userRepository, never()).save(any()); |
217 | 234 |
} |
218 | 235 |
|
236 |
@Test |
|
237 |
void testCanNotResetSuperAdminPassword() { |
|
238 |
// given |
|
239 |
String email = "admin@admin.com"; |
|
240 |
String newPassword = "password123"; |
|
241 |
|
|
242 |
// when |
|
243 |
// then |
|
244 |
assertThatThrownBy(() -> underTest.resetPassword(email, newPassword)) |
|
245 |
.isInstanceOf(ApiRequestException.class) |
|
246 |
.hasMessageContaining("Password for SUPER ADMIN can not be changed"); |
|
247 |
|
|
248 |
verify(userRepository, never()).save(any()); |
|
249 |
verify(userRepository, never()).findByEmail(any()); |
|
250 |
} |
|
251 |
|
|
219 | 252 |
@Test |
220 | 253 |
void testCanDeleteUser() { |
221 | 254 |
// given |
... | ... | |
267 | 300 |
UserEntity userEntity1 = new UserEntity("first", "first@test.com", "password", (byte) 0, false); |
268 | 301 |
UserEntity userEntity2 = new UserEntity("second", "second@test.com", "password2", (byte) 1, false); |
269 | 302 |
UserEntity userEntity3 = new UserEntity("third", "third@test.com", "password3", (byte) 7, true); |
303 |
UserEntity userEntity4 = new UserEntity("SuperAdmin", "admin@admin.com", "password3", (byte) 7, true); |
|
270 | 304 |
|
271 | 305 |
UserDto userDto1 = new UserDto("first", "first@test.com", new PermissionDto(), null); |
272 | 306 |
UserDto userDto2 = new UserDto("second", "second@test.com", new PermissionDto(true, false, false), null); |
273 | 307 |
UserDto userDto3 = new UserDto("third", "third@test.com", new PermissionDto(true, true, true), null); |
274 | 308 |
|
275 |
given(userRepository.findAll()).willReturn(List.of(userEntity1, userEntity2, userEntity3)); |
|
309 |
given(userRepository.findAll()).willReturn(List.of(userEntity1, userEntity2, userEntity3, userEntity4));
|
|
276 | 310 |
|
277 | 311 |
// when |
278 | 312 |
List<UserDto> allUsers = underTest.getAllUsers(); |
... | ... | |
344 | 378 |
|
345 | 379 |
verify(userRepository, never()).save(any()); |
346 | 380 |
} |
381 |
|
|
382 |
@Test |
|
383 |
void testCanNotChangePasswordSuperAdmin() { |
|
384 |
// given |
|
385 |
String email = "admin@admin.com"; |
|
386 |
String oldPassword = "password"; |
|
387 |
String newPassword = "password123"; |
|
388 |
UserEntity userEntity = new UserEntity("John Doe", email, bCryptPasswordEncoder.encode(oldPassword), (byte) 7, true); |
|
389 |
SecurityContext securityContext = mock(SecurityContext.class); |
|
390 |
Authentication authentication = mock(Authentication.class); |
|
391 |
given(securityContext.getAuthentication()).willReturn(authentication); |
|
392 |
SecurityContextHolder.setContext(securityContext); |
|
393 |
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, null, Collections.emptySet()); |
|
394 |
SecurityContextHolder.getContext().setAuthentication(authenticationToken); |
|
395 |
given(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).willReturn(email); |
|
396 |
given(userRepository.findByEmail(email)).willReturn(Optional.of(userEntity)); |
|
397 |
|
|
398 |
// when |
|
399 |
// then |
|
400 |
assertThatThrownBy(() -> underTest.changePassword(oldPassword, newPassword)) |
|
401 |
.isInstanceOf(ApiRequestException.class) |
|
402 |
.hasMessageContaining("Can not change password for SUPER ADMIN"); |
|
403 |
|
|
404 |
verify(userRepository, never()).save(any()); |
|
405 |
} |
|
347 | 406 |
} |
frontend/package.json | ||
---|---|---|
10 | 10 |
"@mui/icons-material": "^5.5.1", |
11 | 11 |
"@mui/material": "^5.5.2", |
12 | 12 |
"@reduxjs/toolkit": "^1.8.1", |
13 |
"axios": "^0.26.0",
|
|
13 |
"axios": "^0.27.2",
|
|
14 | 14 |
"dompurify": "^2.3.6", |
15 | 15 |
"dotenv": "^16.0.0", |
16 | 16 |
"formik": "^2.2.9", |
frontend/yarn.lock | ||
---|---|---|
2825 | 2825 |
dependencies: |
2826 | 2826 |
follow-redirects "^1.14.0" |
2827 | 2827 |
|
2828 |
axios@^0.26.0:
|
|
2829 |
version "0.26.0"
|
|
2830 |
resolved "https://registry.yarnpkg.com/axios/-/axios-0.26.0.tgz#9a318f1c69ec108f8cd5f3c3d390366635e13928"
|
|
2831 |
integrity sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==
|
|
2828 |
axios@^0.27.2:
|
|
2829 |
version "0.27.2"
|
|
2830 |
resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
|
|
2831 |
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
|
|
2832 | 2832 |
dependencies: |
2833 |
follow-redirects "^1.14.8" |
|
2833 |
follow-redirects "^1.14.9" |
|
2834 |
form-data "^4.0.0" |
|
2834 | 2835 |
|
2835 | 2836 |
axobject-query@^2.2.0: |
2836 | 2837 |
version "2.2.0" |
... | ... | |
4726 | 4727 |
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" |
4727 | 4728 |
integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== |
4728 | 4729 |
|
4729 |
follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.8:
|
|
4730 |
follow-redirects@^1.0.0, follow-redirects@^1.14.0: |
|
4730 | 4731 |
version "1.14.9" |
4731 | 4732 |
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.9.tgz#dd4ea157de7bfaf9ea9b3fbd85aa16951f78d8d7" |
4732 | 4733 |
integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== |
4733 | 4734 |
|
4735 |
follow-redirects@^1.14.9: |
|
4736 |
version "1.15.0" |
|
4737 |
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.0.tgz#06441868281c86d0dda4ad8bdaead2d02dca89d4" |
|
4738 |
integrity sha512-aExlJShTV4qOUOL7yF1U5tvLCB0xQuudbf6toyYA0E/acBNw71mvjFTnLaRp50aQaYocMR0a/RMMBIHeZnGyjQ== |
|
4739 |
|
|
4734 | 4740 |
fork-ts-checker-webpack-plugin@^6.5.0: |
4735 | 4741 |
version "6.5.0" |
4736 | 4742 |
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.0.tgz#0282b335fa495a97e167f69018f566ea7d2a2b5e" |
... | ... | |
4759 | 4765 |
combined-stream "^1.0.8" |
4760 | 4766 |
mime-types "^2.1.12" |
4761 | 4767 |
|
4768 |
form-data@^4.0.0: |
|
4769 |
version "4.0.0" |
|
4770 |
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" |
|
4771 |
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== |
|
4772 |
dependencies: |
|
4773 |
asynckit "^0.4.0" |
|
4774 |
combined-stream "^1.0.8" |
|
4775 |
mime-types "^2.1.12" |
|
4776 |
|
|
4762 | 4777 |
formik@^2.2.9: |
4763 | 4778 |
version "2.2.9" |
4764 | 4779 |
resolved "https://registry.yarnpkg.com/formik/-/formik-2.2.9.tgz#8594ba9c5e2e5cf1f42c5704128e119fc46232d0" |
Také k dispozici: Unified diff
Added Super Admin user
re #9790