From 159bcac5c42fb76835498445a47a8db2c2b44d71 Mon Sep 17 00:00:00 2001 From: ThisBirchWood Date: Wed, 2 Jul 2025 22:03:39 +0200 Subject: [PATCH] MOVE user authentication and clip creation to ClipService --- frontend/src/utils/endpoints.ts | 2 + .../java/com/ddf/vodsystem/entities/Job.java | 4 ++ .../ddf/vodsystem/services/ClipService.java | 42 +++++++++++++++++-- .../ddf/vodsystem/services/EditService.java | 34 +-------------- .../ddf/vodsystem/services/JobService.java | 15 +++++++ 5 files changed, 61 insertions(+), 36 deletions(-) diff --git a/frontend/src/utils/endpoints.ts b/frontend/src/utils/endpoints.ts index a5b20fe..43933d1 100644 --- a/frontend/src/utils/endpoints.ts +++ b/frontend/src/utils/endpoints.ts @@ -119,6 +119,8 @@ const getMetadata = async (uuid: string): Promise => { console.error('Error fetching metadata:', error); return { + title: '', + description: '', startPoint: 0, endPoint: 0, fps: 0, diff --git a/src/main/java/com/ddf/vodsystem/entities/Job.java b/src/main/java/com/ddf/vodsystem/entities/Job.java index 3038af4..4f1c6ad 100644 --- a/src/main/java/com/ddf/vodsystem/entities/Job.java +++ b/src/main/java/com/ddf/vodsystem/entities/Job.java @@ -1,6 +1,7 @@ package com.ddf.vodsystem.entities; import java.io.File; +import org.springframework.security.core.context.SecurityContext; import lombok.Data; @@ -14,6 +15,9 @@ public class Job { private VideoMetadata inputVideoMetadata; private VideoMetadata outputVideoMetadata = new VideoMetadata(); + // security + private SecurityContext securityContext; + // job status private JobStatus status = JobStatus.NOT_READY; private Float progress = 0.0f; diff --git a/src/main/java/com/ddf/vodsystem/services/ClipService.java b/src/main/java/com/ddf/vodsystem/services/ClipService.java index 012bb77..b1aaadc 100644 --- a/src/main/java/com/ddf/vodsystem/services/ClipService.java +++ b/src/main/java/com/ddf/vodsystem/services/ClipService.java @@ -1,21 +1,24 @@ package com.ddf.vodsystem.services; -import com.ddf.vodsystem.entities.VideoMetadata; -import com.ddf.vodsystem.entities.JobStatus; -import com.ddf.vodsystem.entities.Job; +import com.ddf.vodsystem.entities.*; import java.io.BufferedReader; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import com.ddf.vodsystem.exceptions.FFMPEGException; +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 @@ -26,8 +29,13 @@ public class ClipService { private static final float MAX_AUDIO_BITRATE = 128f; private static final float BITRATE_MULTIPLIER = 0.9f; + private final ClipRepository clipRepository; private final Pattern timePattern = Pattern.compile("out_time_ms=(\\d+)"); + public ClipService(ClipRepository clipRepository) { + this.clipRepository = clipRepository; + } + public void run(Job job) throws IOException, InterruptedException { logger.info("FFMPEG starting..."); @@ -56,10 +64,23 @@ public class ClipService { throw new FFMPEGException("FFMPEG process failed"); } + User user = getUser(); + if (user != null) { + createClip(job.getOutputVideoMetadata(), user); + } + job.setStatus(JobStatus.FINISHED); logger.info("FFMPEG finished"); } + private User getUser() { + Authentication auth = SecurityContextHolder.getContext().getAuthentication(); + if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof CustomOAuth2User oAuth2user) { + return oAuth2user.getUser(); + } + return null; + } + private void validateVideoMetadata(VideoMetadata inputFileMetadata, VideoMetadata outputFileMetadata) { if (outputFileMetadata.getStartPoint() == null) { outputFileMetadata.setStartPoint(0f); @@ -141,4 +162,19 @@ public class ClipService { return new ProcessBuilder(command); } + private void createClip(VideoMetadata videoMetadata, User user) { + Clip clip = new Clip(); + clip.setTitle(videoMetadata.getTitle() != null ? videoMetadata.getTitle() : "Untitled Clip"); + clip.setUser(user); + clip.setDescription(videoMetadata.getDescription()); + clip.setCreatedAt(LocalDateTime.now()); + clip.setWidth(videoMetadata.getWidth()); + clip.setHeight(videoMetadata.getHeight()); + clip.setFps(videoMetadata.getFps()); + clip.setDuration(videoMetadata.getEndPoint() - videoMetadata.getStartPoint()); + clip.setFileSize(videoMetadata.getFileSize()); + clip.setVideoPath("test"); + clipRepository.save(clip); + } + } diff --git a/src/main/java/com/ddf/vodsystem/services/EditService.java b/src/main/java/com/ddf/vodsystem/services/EditService.java index f749e32..5ccf654 100644 --- a/src/main/java/com/ddf/vodsystem/services/EditService.java +++ b/src/main/java/com/ddf/vodsystem/services/EditService.java @@ -1,24 +1,15 @@ package com.ddf.vodsystem.services; import com.ddf.vodsystem.entities.*; -import com.ddf.vodsystem.repositories.ClipRepository; -import com.ddf.vodsystem.security.CustomOAuth2User; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; -import java.time.LocalDateTime; - @Service public class EditService { private final JobService jobService; - private final ClipRepository clipRepository; - private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(EditService.class); - public EditService(JobService jobService, ClipRepository clipRepository) { + public EditService(JobService jobService) { this.jobService = jobService; - this.clipRepository = clipRepository; } public void edit(String uuid, VideoMetadata videoMetadata) { @@ -29,15 +20,6 @@ public class EditService { public void process(String uuid) { jobService.jobReady(uuid); - Authentication auth = SecurityContextHolder.getContext().getAuthentication(); - - if (auth != null && auth.isAuthenticated() && auth.getPrincipal() instanceof CustomOAuth2User oAuth2user) { - logger.debug("Saving clip {} for user {}", uuid, oAuth2user.getName()); - VideoMetadata videoMetadata = jobService.getJob(uuid).getOutputVideoMetadata(); - User user = oAuth2user.getUser(); - - createClip(videoMetadata, user); - } } public float getProgress(String uuid) { @@ -87,18 +69,4 @@ public class EditService { } } - private void createClip(VideoMetadata videoMetadata, User user) { - Clip clip = new Clip(); - clip.setTitle("test"); - clip.setUser(user); - clip.setDescription("This is a test"); - clip.setCreatedAt(LocalDateTime.now()); - clip.setWidth(videoMetadata.getWidth()); - clip.setHeight(videoMetadata.getHeight()); - clip.setFps(videoMetadata.getFps()); - clip.setDuration(videoMetadata.getEndPoint() - videoMetadata.getStartPoint()); - clip.setFileSize(videoMetadata.getFileSize()); - clip.setVideoPath("test"); - clipRepository.save(clip); - } } diff --git a/src/main/java/com/ddf/vodsystem/services/JobService.java b/src/main/java/com/ddf/vodsystem/services/JobService.java index 6b752f0..ec15b0d 100644 --- a/src/main/java/com/ddf/vodsystem/services/JobService.java +++ b/src/main/java/com/ddf/vodsystem/services/JobService.java @@ -7,6 +7,8 @@ import java.util.concurrent.LinkedBlockingQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.security.core.context.SecurityContext; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import com.ddf.vodsystem.entities.Job; @@ -67,6 +69,9 @@ public class JobService { Job job = getJob(uuid); job.setProgress(0f); + SecurityContext context = SecurityContextHolder.getContext(); + job.setSecurityContext(context); + logger.info("Job ready: {}", job.getUuid()); job.setStatus(JobStatus.PENDING); jobQueue.add(job); @@ -77,11 +82,21 @@ public class JobService { * @param job the job to process */ private void processJob(Job job) { + SecurityContext previousContext = SecurityContextHolder.getContext(); // optional, for restoring later try { + if (job.getSecurityContext() != null) { + SecurityContextHolder.setContext(job.getSecurityContext()); + } + clipService.run(job); + } catch (IOException | InterruptedException e) { Thread.currentThread().interrupt(); logger.error("Error while running job {}", job.getUuid(), e); + + } finally { + // 🔄 Restore previous context to avoid leaking across jobs + SecurityContextHolder.setContext(previousContext); } }