From f6e6aae5c6ae709a4a6ae92f436f499e501f6154 Mon Sep 17 00:00:00 2001 From: ThisBirchWood Date: Wed, 23 Jul 2025 00:00:45 +0200 Subject: [PATCH] ADD user authentication checks for clip access --- .../ddf/vodsystem/services/ClipService.java | 44 ++++++++++++------- .../vodsystem/services/DirectoryService.java | 19 -------- .../vodsystem/services/DownloadService.java | 16 ++++++- .../ddf/vodsystem/services/FfmpegService.java | 6 +-- .../ddf/vodsystem/services/UserService.java | 18 ++++++++ 5 files changed, 65 insertions(+), 38 deletions(-) create mode 100644 src/main/java/com/ddf/vodsystem/services/UserService.java diff --git a/src/main/java/com/ddf/vodsystem/services/ClipService.java b/src/main/java/com/ddf/vodsystem/services/ClipService.java index a32a6cb..1c826f3 100644 --- a/src/main/java/com/ddf/vodsystem/services/ClipService.java +++ b/src/main/java/com/ddf/vodsystem/services/ClipService.java @@ -8,12 +8,10 @@ import java.io.IOException; import java.time.LocalDateTime; import java.util.List; +import com.ddf.vodsystem.exceptions.NotAuthenticated; import com.ddf.vodsystem.repositories.ClipRepository; -import com.ddf.vodsystem.security.CustomOAuth2User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; @Service @@ -24,15 +22,18 @@ public class ClipService { private final MetadataService metadataService; private final DirectoryService directoryService; private final FfmpegService ffmpegService; + private final UserService userService; public ClipService(ClipRepository clipRepository, MetadataService metadataService, DirectoryService directoryService, - FfmpegService ffmpegService) { + FfmpegService ffmpegService, + UserService userService) { this.clipRepository = clipRepository; this.metadataService = metadataService; this.directoryService = directoryService; this.ffmpegService = ffmpegService; + this.userService = userService; } /** @@ -53,7 +54,7 @@ public class ClipService { Float fileSize = metadataService.getFileSize(job.getOutputFile()); job.getOutputVideoMetadata().setFileSize(fileSize); - User user = getUser(); + User user = userService.getUser(); if (user != null) { persistClip(job.getOutputVideoMetadata(), user, job); } @@ -63,7 +64,7 @@ public class ClipService { } public List getClipsByUser() { - User user = getUser(); + User user = userService.getUser(); if (user == null) { logger.warn("No authenticated user found"); @@ -73,14 +74,31 @@ public class ClipService { return clipRepository.findByUser(user); } - private User getUser() { - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof CustomOAuth2User oAuth2user) { - return oAuth2user.getUser(); + public Clip getClipById(Long id) { + Clip clip = clipRepository.findById(id).orElse(null); + + if (clip == null) { + logger.warn("Clip with ID {} not found", id); + return null; } - return null; + + if (!isAuthenticatedForClip(clip)) { + logger.warn("User is not authorized to access clip with ID {}", id); + throw new NotAuthenticated("You are not authorized to access this clip"); + } + + return clip; } + public boolean isAuthenticatedForClip(Clip clip) { + User user = userService.getUser(); + if (user == null || clip == null) { + return false; + } + return user.getId().equals(clip.getUser().getId()); + } + + private void persistClip(VideoMetadata videoMetadata, User user, Job job) { // Move clip from temp to output directory String fileExtension = directoryService.getFileExtension(job.getOutputFile().getAbsolutePath()); @@ -114,8 +132,4 @@ public class ClipService { clip.setThumbnailPath(thumbnailOutputFile.getPath()); clipRepository.save(clip); } - - public Clip getClipById(Long id) { - return clipRepository.findById(id).orElse(null); - } } diff --git a/src/main/java/com/ddf/vodsystem/services/DirectoryService.java b/src/main/java/com/ddf/vodsystem/services/DirectoryService.java index eb74e90..273cdbc 100644 --- a/src/main/java/com/ddf/vodsystem/services/DirectoryService.java +++ b/src/main/java/com/ddf/vodsystem/services/DirectoryService.java @@ -42,25 +42,6 @@ public class DirectoryService { return new File(dir); } - public File getOutputFile(String id, String extension) { - if (id == null || id.length() < 2) { - throw new IllegalArgumentException("ID must be at least 2 characters long"); - } - - // Create subdirectories from first 2 characters of the ID - String shard1 = id.substring(0, 2); - String shard2 = id.substring(2); - - String dir = outputDir + - File.separator + - shard1 + - File.separator + - shard2 + - (extension.isEmpty() ? "" : "." + extension); - - return new File(dir); - } - public File getUserClipsDir(Long userId) { if (userId == null) { throw new IllegalArgumentException("User ID cannot be null"); diff --git a/src/main/java/com/ddf/vodsystem/services/DownloadService.java b/src/main/java/com/ddf/vodsystem/services/DownloadService.java index 24345b7..74e33da 100644 --- a/src/main/java/com/ddf/vodsystem/services/DownloadService.java +++ b/src/main/java/com/ddf/vodsystem/services/DownloadService.java @@ -5,6 +5,7 @@ import com.ddf.vodsystem.entities.JobStatus; import com.ddf.vodsystem.exceptions.JobNotFinished; import com.ddf.vodsystem.exceptions.JobNotFound; import com.ddf.vodsystem.entities.Job; +import com.ddf.vodsystem.exceptions.NotAuthenticated; import com.ddf.vodsystem.repositories.ClipRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.io.FileSystemResource; @@ -18,11 +19,15 @@ public class DownloadService { private final JobService jobService; private final ClipRepository clipRepository; + private final ClipService clipService; @Autowired - public DownloadService(JobService jobService, ClipRepository clipRepository) { + public DownloadService(JobService jobService, + ClipRepository clipRepository, + ClipService clipService) { this.jobService = jobService; this.clipRepository = clipRepository; + this.clipService = clipService; } public Resource downloadInput(String uuid) { @@ -52,8 +57,13 @@ public class DownloadService { } public Resource downloadClip(Clip clip) { + if (!clipService.isAuthenticatedForClip(clip)) { + throw new NotAuthenticated("Not authenticated for this clip"); + } + String path = clip.getVideoPath(); File file = new File(path); + if (!file.exists()) { throw new JobNotFound("Clip file not found"); } @@ -67,6 +77,10 @@ public class DownloadService { } public Resource downloadThumbnail(Clip clip) { + if (!clipService.isAuthenticatedForClip(clip)) { + throw new NotAuthenticated("Not authenticated for this clip thumbnail"); + } + String path = clip.getThumbnailPath(); File file = new File(path); if (!file.exists()) { diff --git a/src/main/java/com/ddf/vodsystem/services/FfmpegService.java b/src/main/java/com/ddf/vodsystem/services/FfmpegService.java index 24379ce..e85ca4c 100644 --- a/src/main/java/com/ddf/vodsystem/services/FfmpegService.java +++ b/src/main/java/com/ddf/vodsystem/services/FfmpegService.java @@ -48,13 +48,13 @@ public class FfmpegService { runWithProgress(inputFile, outputFile, videoMetadata, new AtomicReference<>(0f)); } - public void generateThumbnail(File inputFile, File outputFile, Float time) throws IOException, InterruptedException { - logger.info("Generating thumbnail at {} seconds", time); + public void generateThumbnail(File inputFile, File outputFile, Float timeInVideo) throws IOException, InterruptedException { + logger.info("Generating thumbnail at {} seconds", timeInVideo); List command = new ArrayList<>(); command.add("ffmpeg"); command.add("-ss"); - command.add(time.toString()); + command.add(timeInVideo.toString()); command.add("-i"); command.add(inputFile.getAbsolutePath()); command.add("-frames:v"); diff --git a/src/main/java/com/ddf/vodsystem/services/UserService.java b/src/main/java/com/ddf/vodsystem/services/UserService.java new file mode 100644 index 0000000..946dbfe --- /dev/null +++ b/src/main/java/com/ddf/vodsystem/services/UserService.java @@ -0,0 +1,18 @@ +package com.ddf.vodsystem.services; + +import com.ddf.vodsystem.entities.User; +import com.ddf.vodsystem.security.CustomOAuth2User; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +@Service +public class UserService { + public User getUser() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof CustomOAuth2User oAuth2user) { + return oAuth2user.getUser(); + } + return null; + } +}