Compare commits
No commits in common. "02c7e8887e62cf37b395632e4651ca39507b95d0" and "45c71ed0d88a0735eb20774824bfceb387faa045" have entirely different histories.
02c7e8887e
...
45c71ed0d8
@ -188,7 +188,7 @@ public class ImageControllerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uploadImage() throws Exception {
|
||||
public void putImage() throws Exception {
|
||||
final User owner = this.seedUser();
|
||||
final String accessToken = this.getAccessToken(owner);
|
||||
try (final InputStream hal9000 = getHal9000InputStream()) {
|
||||
|
||||
@ -2,13 +2,12 @@ package app.mealsmadeeasy.api.image;
|
||||
|
||||
import app.mealsmadeeasy.api.image.body.ImageUpdateBody;
|
||||
import app.mealsmadeeasy.api.image.converter.ImageToViewConverter;
|
||||
import app.mealsmadeeasy.api.image.converter.ImageUpdateBodyToSpecConverter;
|
||||
import app.mealsmadeeasy.api.image.spec.ImageCreateSpec;
|
||||
import app.mealsmadeeasy.api.image.spec.ImageUpdateSpec;
|
||||
import app.mealsmadeeasy.api.image.view.ImageView;
|
||||
import app.mealsmadeeasy.api.user.User;
|
||||
import app.mealsmadeeasy.api.user.UserService;
|
||||
import app.mealsmadeeasy.api.util.AccessDeniedView;
|
||||
import app.mealsmadeeasy.api.util.ResourceExistsView;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.io.InputStreamResource;
|
||||
import org.springframework.http.HttpStatus;
|
||||
@ -33,7 +32,27 @@ public class ImageController {
|
||||
private final ImageService imageService;
|
||||
private final UserService userService;
|
||||
private final ImageToViewConverter imageToViewConverter;
|
||||
private final ImageUpdateBodyToSpecConverter imageUpdateBodyToSpecConverter;
|
||||
|
||||
private ImageUpdateSpec getImageUpdateSpec(ImageUpdateBody body) {
|
||||
final var builder = ImageUpdateSpec.builder()
|
||||
.alt(body.getAlt())
|
||||
.caption(body.getCaption())
|
||||
.isPublic(body.getIsPublic())
|
||||
.clearAllViewers(body.getClearAllViewers());
|
||||
if (body.getViewersToAdd() != null) {
|
||||
builder.viewersToAdd(body.getViewersToAdd().stream()
|
||||
.map(this.userService::getUser)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
if (body.getViewersToRemove() != null) {
|
||||
builder.viewersToRemove(body.getViewersToRemove().stream()
|
||||
.map(this.userService::getUser)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@ExceptionHandler
|
||||
public ResponseEntity<AccessDeniedView> onAccessDenied(AccessDeniedException e) {
|
||||
@ -62,8 +81,8 @@ public class ImageController {
|
||||
.body(new InputStreamResource(imageInputStream));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<ImageView> uploadImage(
|
||||
@PutMapping
|
||||
public ResponseEntity<ImageView> putImage(
|
||||
@RequestParam MultipartFile image,
|
||||
@RequestParam String filename,
|
||||
@RequestParam(required = false) String alt,
|
||||
@ -90,7 +109,7 @@ public class ImageController {
|
||||
return ResponseEntity.status(201).body(this.imageToViewConverter.convert(saved, principal, true));
|
||||
}
|
||||
|
||||
@PutMapping("/{username}/{filename}")
|
||||
@PostMapping("/{username}/{filename}")
|
||||
public ResponseEntity<ImageView> updateInfo(
|
||||
@AuthenticationPrincipal User principal,
|
||||
@PathVariable String username,
|
||||
@ -99,24 +118,10 @@ public class ImageController {
|
||||
) {
|
||||
final User owner = this.userService.getUser(username);
|
||||
final Image image = this.imageService.getByOwnerAndFilename(owner, filename, principal);
|
||||
final Image updated = this.imageService.update(
|
||||
image,
|
||||
principal,
|
||||
this.imageUpdateBodyToSpecConverter.convert(body)
|
||||
);
|
||||
final Image updated = this.imageService.update(image, principal, this.getImageUpdateSpec(body));
|
||||
return ResponseEntity.ok(this.imageToViewConverter.convert(updated, principal, true));
|
||||
}
|
||||
|
||||
@GetMapping("/{username}/{filename}/exists")
|
||||
public ResponseEntity<ResourceExistsView> resourceExists(
|
||||
@AuthenticationPrincipal User principal,
|
||||
@PathVariable String username,
|
||||
@PathVariable String filename
|
||||
) {
|
||||
final boolean exists = this.imageService.exists(principal, username, filename);
|
||||
return ResponseEntity.ok(new ResourceExistsView(exists));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{username}/{filename}")
|
||||
public ResponseEntity<Object> deleteImage(
|
||||
@AuthenticationPrincipal User principal,
|
||||
|
||||
@ -12,7 +12,6 @@ public class ImageEndpointAuthConfigurator implements EndpointAuthConfigurator {
|
||||
@Override
|
||||
public void configure(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
|
||||
registry.requestMatchers(HttpMethod.GET, "/images/**").permitAll();
|
||||
registry.requestMatchers(HttpMethod.GET, "/images/*/*/exists").authenticated();
|
||||
registry.requestMatchers(HttpMethod.POST, "/images/**").authenticated();
|
||||
registry.requestMatchers(HttpMethod.PUT, "/images/**").authenticated();
|
||||
registry.requestMatchers(HttpMethod.DELETE, "/images/**").authenticated();
|
||||
|
||||
@ -6,5 +6,4 @@ import org.jetbrains.annotations.Nullable;
|
||||
public interface ImageSecurity {
|
||||
boolean isViewableBy(Image image, @Nullable User viewer);
|
||||
boolean isOwner(Image image, @Nullable User user);
|
||||
boolean canSeeExists(User viewer, String username, String filename);
|
||||
}
|
||||
|
||||
@ -45,9 +45,4 @@ public class ImageSecurityImpl implements ImageSecurity {
|
||||
return image.getOwner() != null && user != null && Objects.equals(image.getOwner().getId(), user.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canSeeExists(User viewer, String username, String filename) {
|
||||
return viewer.getUsername().equals(username);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -21,8 +21,6 @@ public interface ImageService {
|
||||
InputStream getImageContent(Image image, @Nullable User viewer) throws IOException;
|
||||
List<Image> getImagesOwnedBy(User user);
|
||||
|
||||
boolean exists(User viewer, String username, String filename);
|
||||
|
||||
Image update(Image image, User modifier, ImageUpdateSpec spec);
|
||||
|
||||
void deleteImage(Image image, User modifier) throws IOException;
|
||||
|
||||
@ -196,12 +196,6 @@ public class S3ImageService implements ImageService {
|
||||
return new ArrayList<>(this.imageRepository.findAllByOwner(user));
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("@imageSecurity.canSeeExists(#viewer, #username, #filename)")
|
||||
public boolean exists(User viewer, String username, String filename) {
|
||||
return this.imageRepository.findByOwnerUsernameAndFilename(username, filename).isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
@PreAuthorize("@imageSecurity.isOwner(#image, #modifier)")
|
||||
public Image update(final Image image, User modifier, ImageUpdateSpec updateSpec) {
|
||||
|
||||
@ -1,38 +0,0 @@
|
||||
package app.mealsmadeeasy.api.image.converter;
|
||||
|
||||
import app.mealsmadeeasy.api.image.body.ImageUpdateBody;
|
||||
import app.mealsmadeeasy.api.image.spec.ImageUpdateSpec;
|
||||
import app.mealsmadeeasy.api.user.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ImageUpdateBodyToSpecConverter {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
public ImageUpdateSpec convert(ImageUpdateBody body) {
|
||||
final var builder = ImageUpdateSpec.builder()
|
||||
.alt(body.getAlt())
|
||||
.caption(body.getCaption())
|
||||
.isPublic(body.getIsPublic())
|
||||
.clearAllViewers(body.getClearAllViewers());
|
||||
if (body.getViewersToAdd() != null) {
|
||||
builder.viewersToAdd(body.getViewersToAdd().stream()
|
||||
.map(this.userService::getUser)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
if (body.getViewersToRemove() != null) {
|
||||
builder.viewersToRemove(body.getViewersToRemove().stream()
|
||||
.map(this.userService::getUser)
|
||||
.collect(Collectors.toSet())
|
||||
);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
package app.mealsmadeeasy.api.util;
|
||||
|
||||
public record ResourceExistsView(boolean exists) {}
|
||||
Loading…
Reference in New Issue
Block a user