Skip to content

Commit d2223bb

Browse files
committed
(TP-77) feat: add validation sender is owner or admin
1 parent 0846610 commit d2223bb

3 files changed

Lines changed: 50 additions & 11 deletions

File tree

rentplace/src/main/java/kattsyn/dev/rentplace/controllers/PropertyController.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.springframework.http.MediaType;
1919
import org.springframework.http.ResponseEntity;
2020
import org.springframework.security.access.prepost.PreAuthorize;
21+
import org.springframework.security.core.Authentication;
2122
import org.springframework.validation.annotation.Validated;
2223
import org.springframework.web.bind.annotation.*;
2324
import org.springframework.web.multipart.MultipartFile;
@@ -43,17 +44,18 @@ public class PropertyController {
4344
@ApiResponse(responseCode = "413", description = "Превышен максимальный размер запроса"),
4445
@ApiResponse(responseCode = "500", description = "Внутренняя ошибка сервера")
4546
})
46-
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
47+
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
4748
@SecurityRequirement(name = "JWT")
4849
public ResponseEntity<List<ImageDTO>> uploadMultipleImages(
4950
@PathVariable @Parameter(description = "id объявления", example = "10") long id,
5051
@Parameter(
5152
description = "Массив файлов фотографий",
5253
required = true,
5354
content = @Content(mediaType = MediaType.MULTIPART_FORM_DATA_VALUE, schema = @Schema(type = "string", format = "binary"))
54-
) @RequestPart("files") MultipartFile[] files) {
55-
55+
) @RequestPart("files") MultipartFile[] files,
56+
Authentication authentication) {
5657

58+
propertyService.ownsPropertyOrAdmin(id, authentication.getName());
5759
List<ImageDTO> savedImages = propertyService.uploadImages(files, id);
5860

5961
return ResponseEntity.ok(savedImages);
@@ -104,10 +106,11 @@ public ResponseEntity<PropertyDTO> findById(@Valid @PathVariable @Parameter(desc
104106
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
105107
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
106108
})
107-
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
109+
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
108110
@SecurityRequirement(name = "JWT")
109111
@PostMapping(path = "/", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
110-
public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO) {
112+
public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO, Authentication authentication) {
113+
propertyService.allowedToCreatePropertyOrAdmin(propertyCreateEditDTO, authentication.getName());
111114
return new ResponseEntity<>(propertyService.createWithImages(propertyCreateEditDTO), HttpStatus.CREATED);
112115
}
113116

@@ -122,11 +125,13 @@ public ResponseEntity<PropertyDTO> createPropertyWithImage(@Valid @ModelAttribut
122125
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
123126
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
124127
})
125-
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')" )
128+
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
126129
@SecurityRequirement(name = "JWT")
127130
@PatchMapping(path = "/{id}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
128131
public ResponseEntity<PropertyDTO> updateProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "1") long id,
129-
@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO) {
132+
@Valid @ModelAttribute PropertyCreateEditDTO propertyCreateEditDTO,
133+
Authentication authentication) {
134+
propertyService.ownsPropertyOrAdmin(id, authentication.getName());
130135
return ResponseEntity.ok(propertyService.update(id, propertyCreateEditDTO));
131136
}
132137

@@ -141,11 +146,13 @@ public ResponseEntity<PropertyDTO> updateProperty(@Valid @PathVariable @Paramete
141146
@ApiResponse(responseCode = "422", description = "Ошибка валидации", content = @Content),
142147
@ApiResponse(responseCode = "500", description = "Непредвиденная ошибка со стороны сервера", content = @Content)
143148
})
144-
@PreAuthorize("hasAuthority('ROLE_ADMIN')" )
149+
@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
145150
@SecurityRequirement(name = "JWT")
146151
@DeleteMapping("/{id}")
147-
public ResponseEntity<Void> deleteProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "10") long id) {
148-
propertyService.deleteById(id);
152+
public ResponseEntity<Void> deleteProperty(@Valid @PathVariable @Parameter(description = "id объявления", example = "10") long id, Authentication authentication) {
153+
if (propertyService.ownsPropertyOrAdmin(id, authentication.getName())) {
154+
propertyService.deleteById(id);
155+
}
149156
return ResponseEntity.noContent().build();
150157
}
151158
}

rentplace/src/main/java/kattsyn/dev/rentplace/services/PropertyService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
public interface PropertyService {
1212

13+
boolean ownsPropertyOrAdmin(long propertyId, String email);
14+
15+
boolean allowedToCreatePropertyOrAdmin(PropertyCreateEditDTO propertyCreateEditDTO, String email);
16+
1317
List<PropertyDTO> findAll();
1418

1519
PropertyDTO findById(long id);

rentplace/src/main/java/kattsyn/dev/rentplace/services/impl/PropertyServiceImpl.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,17 @@
66
import kattsyn.dev.rentplace.dtos.PropertyDTO;
77
import kattsyn.dev.rentplace.entities.Image;
88
import kattsyn.dev.rentplace.entities.Property;
9+
import kattsyn.dev.rentplace.entities.User;
910
import kattsyn.dev.rentplace.enums.ImageType;
11+
import kattsyn.dev.rentplace.enums.Role;
12+
import kattsyn.dev.rentplace.exceptions.ForbiddenException;
13+
import kattsyn.dev.rentplace.exceptions.NotFoundException;
1014
import kattsyn.dev.rentplace.mappers.ImageMapper;
1115
import kattsyn.dev.rentplace.mappers.PropertyMapper;
1216
import kattsyn.dev.rentplace.repositories.PropertyRepository;
1317
import kattsyn.dev.rentplace.services.ImageService;
1418
import kattsyn.dev.rentplace.services.PropertyService;
19+
import kattsyn.dev.rentplace.services.UserService;
1520
import kattsyn.dev.rentplace.utils.PathResolver;
1621
import lombok.RequiredArgsConstructor;
1722
import org.springframework.stereotype.Service;
@@ -29,6 +34,29 @@ public class PropertyServiceImpl implements PropertyService {
2934
private final PropertyMapper propertyMapper;
3035
private final ImageService imageService;
3136
private final ImageMapper imageMapper;
37+
private final UserService userService;
38+
39+
@Override
40+
@Transactional
41+
public boolean ownsPropertyOrAdmin(long propertyId, String email) {
42+
User user = userService.getUserByEmail(email);
43+
Property property = getPropertyById(propertyId);
44+
45+
if (user.getRole() == Role.ROLE_ADMIN || property.getOwner().getUserId() == user.getUserId()) {
46+
return true;
47+
}
48+
throw new ForbiddenException(String.format("FORBIDDEN. You are not allowed to edit or delete property id: %s.", propertyId));
49+
}
50+
51+
@Override
52+
public boolean allowedToCreatePropertyOrAdmin(PropertyCreateEditDTO propertyCreateEditDTO, String email) {
53+
User user = userService.getUserByEmail(email);
54+
55+
if (user.getRole() == Role.ROLE_ADMIN || user.getUserId() == propertyCreateEditDTO.getOwnerId()) {
56+
return true;
57+
}
58+
throw new ForbiddenException(String.format("FORBIDDEN. You are not allowed to create property for user email: %s.", email));
59+
}
3260

3361
@Transactional
3462
@Override
@@ -40,7 +68,7 @@ public List<PropertyDTO> findAll() {
4068
@Transactional
4169
public Property getPropertyById(long id) {
4270
return propertyRepository.findById(id).orElseThrow(
43-
() -> new IllegalArgumentException(String.format("Property not found with id: %d", id))
71+
() -> new NotFoundException(String.format("Property not found with id: %d", id))
4472
);
4573
}
4674

0 commit comments

Comments
 (0)