ADD user authentication checks for clip access
This commit is contained in:
@@ -8,12 +8,10 @@ import java.io.IOException;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ddf.vodsystem.exceptions.NotAuthenticated;
|
||||||
import com.ddf.vodsystem.repositories.ClipRepository;
|
import com.ddf.vodsystem.repositories.ClipRepository;
|
||||||
import com.ddf.vodsystem.security.CustomOAuth2User;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.core.Authentication;
|
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -24,15 +22,18 @@ public class ClipService {
|
|||||||
private final MetadataService metadataService;
|
private final MetadataService metadataService;
|
||||||
private final DirectoryService directoryService;
|
private final DirectoryService directoryService;
|
||||||
private final FfmpegService ffmpegService;
|
private final FfmpegService ffmpegService;
|
||||||
|
private final UserService userService;
|
||||||
|
|
||||||
public ClipService(ClipRepository clipRepository,
|
public ClipService(ClipRepository clipRepository,
|
||||||
MetadataService metadataService,
|
MetadataService metadataService,
|
||||||
DirectoryService directoryService,
|
DirectoryService directoryService,
|
||||||
FfmpegService ffmpegService) {
|
FfmpegService ffmpegService,
|
||||||
|
UserService userService) {
|
||||||
this.clipRepository = clipRepository;
|
this.clipRepository = clipRepository;
|
||||||
this.metadataService = metadataService;
|
this.metadataService = metadataService;
|
||||||
this.directoryService = directoryService;
|
this.directoryService = directoryService;
|
||||||
this.ffmpegService = ffmpegService;
|
this.ffmpegService = ffmpegService;
|
||||||
|
this.userService = userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,7 +54,7 @@ public class ClipService {
|
|||||||
Float fileSize = metadataService.getFileSize(job.getOutputFile());
|
Float fileSize = metadataService.getFileSize(job.getOutputFile());
|
||||||
job.getOutputVideoMetadata().setFileSize(fileSize);
|
job.getOutputVideoMetadata().setFileSize(fileSize);
|
||||||
|
|
||||||
User user = getUser();
|
User user = userService.getUser();
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
persistClip(job.getOutputVideoMetadata(), user, job);
|
persistClip(job.getOutputVideoMetadata(), user, job);
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ public class ClipService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<Clip> getClipsByUser() {
|
public List<Clip> getClipsByUser() {
|
||||||
User user = getUser();
|
User user = userService.getUser();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
logger.warn("No authenticated user found");
|
logger.warn("No authenticated user found");
|
||||||
@@ -73,14 +74,31 @@ public class ClipService {
|
|||||||
return clipRepository.findByUser(user);
|
return clipRepository.findByUser(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
private User getUser() {
|
public Clip getClipById(Long id) {
|
||||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
Clip clip = clipRepository.findById(id).orElse(null);
|
||||||
if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof CustomOAuth2User oAuth2user) {
|
|
||||||
return oAuth2user.getUser();
|
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) {
|
private void persistClip(VideoMetadata videoMetadata, User user, Job job) {
|
||||||
// Move clip from temp to output directory
|
// Move clip from temp to output directory
|
||||||
String fileExtension = directoryService.getFileExtension(job.getOutputFile().getAbsolutePath());
|
String fileExtension = directoryService.getFileExtension(job.getOutputFile().getAbsolutePath());
|
||||||
@@ -114,8 +132,4 @@ public class ClipService {
|
|||||||
clip.setThumbnailPath(thumbnailOutputFile.getPath());
|
clip.setThumbnailPath(thumbnailOutputFile.getPath());
|
||||||
clipRepository.save(clip);
|
clipRepository.save(clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Clip getClipById(Long id) {
|
|
||||||
return clipRepository.findById(id).orElse(null);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,25 +42,6 @@ public class DirectoryService {
|
|||||||
return new File(dir);
|
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) {
|
public File getUserClipsDir(Long userId) {
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
throw new IllegalArgumentException("User ID cannot be null");
|
throw new IllegalArgumentException("User ID cannot be null");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.ddf.vodsystem.entities.JobStatus;
|
|||||||
import com.ddf.vodsystem.exceptions.JobNotFinished;
|
import com.ddf.vodsystem.exceptions.JobNotFinished;
|
||||||
import com.ddf.vodsystem.exceptions.JobNotFound;
|
import com.ddf.vodsystem.exceptions.JobNotFound;
|
||||||
import com.ddf.vodsystem.entities.Job;
|
import com.ddf.vodsystem.entities.Job;
|
||||||
|
import com.ddf.vodsystem.exceptions.NotAuthenticated;
|
||||||
import com.ddf.vodsystem.repositories.ClipRepository;
|
import com.ddf.vodsystem.repositories.ClipRepository;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.core.io.FileSystemResource;
|
import org.springframework.core.io.FileSystemResource;
|
||||||
@@ -18,11 +19,15 @@ public class DownloadService {
|
|||||||
|
|
||||||
private final JobService jobService;
|
private final JobService jobService;
|
||||||
private final ClipRepository clipRepository;
|
private final ClipRepository clipRepository;
|
||||||
|
private final ClipService clipService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public DownloadService(JobService jobService, ClipRepository clipRepository) {
|
public DownloadService(JobService jobService,
|
||||||
|
ClipRepository clipRepository,
|
||||||
|
ClipService clipService) {
|
||||||
this.jobService = jobService;
|
this.jobService = jobService;
|
||||||
this.clipRepository = clipRepository;
|
this.clipRepository = clipRepository;
|
||||||
|
this.clipService = clipService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Resource downloadInput(String uuid) {
|
public Resource downloadInput(String uuid) {
|
||||||
@@ -52,8 +57,13 @@ public class DownloadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Resource downloadClip(Clip clip) {
|
public Resource downloadClip(Clip clip) {
|
||||||
|
if (!clipService.isAuthenticatedForClip(clip)) {
|
||||||
|
throw new NotAuthenticated("Not authenticated for this clip");
|
||||||
|
}
|
||||||
|
|
||||||
String path = clip.getVideoPath();
|
String path = clip.getVideoPath();
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
throw new JobNotFound("Clip file not found");
|
throw new JobNotFound("Clip file not found");
|
||||||
}
|
}
|
||||||
@@ -67,6 +77,10 @@ public class DownloadService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Resource downloadThumbnail(Clip clip) {
|
public Resource downloadThumbnail(Clip clip) {
|
||||||
|
if (!clipService.isAuthenticatedForClip(clip)) {
|
||||||
|
throw new NotAuthenticated("Not authenticated for this clip thumbnail");
|
||||||
|
}
|
||||||
|
|
||||||
String path = clip.getThumbnailPath();
|
String path = clip.getThumbnailPath();
|
||||||
File file = new File(path);
|
File file = new File(path);
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
|
|||||||
@@ -48,13 +48,13 @@ public class FfmpegService {
|
|||||||
runWithProgress(inputFile, outputFile, videoMetadata, new AtomicReference<>(0f));
|
runWithProgress(inputFile, outputFile, videoMetadata, new AtomicReference<>(0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateThumbnail(File inputFile, File outputFile, Float time) throws IOException, InterruptedException {
|
public void generateThumbnail(File inputFile, File outputFile, Float timeInVideo) throws IOException, InterruptedException {
|
||||||
logger.info("Generating thumbnail at {} seconds", time);
|
logger.info("Generating thumbnail at {} seconds", timeInVideo);
|
||||||
|
|
||||||
List<String> command = new ArrayList<>();
|
List<String> command = new ArrayList<>();
|
||||||
command.add("ffmpeg");
|
command.add("ffmpeg");
|
||||||
command.add("-ss");
|
command.add("-ss");
|
||||||
command.add(time.toString());
|
command.add(timeInVideo.toString());
|
||||||
command.add("-i");
|
command.add("-i");
|
||||||
command.add(inputFile.getAbsolutePath());
|
command.add(inputFile.getAbsolutePath());
|
||||||
command.add("-frames:v");
|
command.add("-frames:v");
|
||||||
|
|||||||
18
src/main/java/com/ddf/vodsystem/services/UserService.java
Normal file
18
src/main/java/com/ddf/vodsystem/services/UserService.java
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user