Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class QAssignment extends EntityPathBase<Assignment> {

public final QBaseEntity _super = new QBaseEntity(this);

public final NumberPath<Long> assignmentId = createNumber("assignmentId", Long.class);
public final ComparablePath<java.util.UUID> assignmentId = createComparable("assignmentId", java.util.UUID.class);

public final hello.cluebackend.domain.classroom.domain.QClassRoom classRoom;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class QAssignmentAttachment extends EntityPathBase<AssignmentAttachment>

public final QAssignment assignment;

public final NumberPath<Long> assignmentAttachmentId = createNumber("assignmentAttachmentId", Long.class);
public final ComparablePath<java.util.UUID> assignmentAttachmentId = createComparable("assignmentAttachmentId", java.util.UUID.class);

public final StringPath contentType = createString("contentType");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class QClassRoom extends EntityPathBase<ClassRoom> {

public static final QClassRoom classRoom = new QClassRoom("classRoom");

public final NumberPath<Long> classRoomId = createNumber("classRoomId", Long.class);
public final ComparablePath<java.util.UUID> classRoomId = createComparable("classRoomId", java.util.UUID.class);

public final ListPath<hello.cluebackend.domain.classroomuser.domain.ClassRoomUser, hello.cluebackend.domain.classroomuser.domain.QClassRoomUser> classRoomUserList = this.<hello.cluebackend.domain.classroomuser.domain.ClassRoomUser, hello.cluebackend.domain.classroomuser.domain.QClassRoomUser>createList("classRoomUserList", hello.cluebackend.domain.classroomuser.domain.ClassRoomUser.class, hello.cluebackend.domain.classroomuser.domain.QClassRoomUser.class, PathInits.DIRECT2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class QClassRoomUser extends EntityPathBase<ClassRoomUser> {

public final hello.cluebackend.domain.classroom.domain.QClassRoom classRoom;

public final NumberPath<Long> classRoomUserId = createNumber("classRoomUserId", Long.class);
public final ComparablePath<java.util.UUID> classRoomUserId = createComparable("classRoomUserId", java.util.UUID.class);

public final hello.cluebackend.domain.user.domain.QUserEntity user;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class QDirectory extends EntityPathBase<Directory> {

public final hello.cluebackend.domain.classroom.domain.QClassRoom classRoom;

public final NumberPath<Long> directoryId = createNumber("directoryId", Long.class);
public final ComparablePath<java.util.UUID> directoryId = createComparable("directoryId", java.util.UUID.class);

public final NumberPath<Integer> directoryOrder = createNumber("directoryOrder", Integer.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class QDocument extends EntityPathBase<Document> {

public final hello.cluebackend.domain.directory.domain.QDirectory directory;

public final NumberPath<Long> documentId = createNumber("documentId", Long.class);
public final ComparablePath<java.util.UUID> documentId = createComparable("documentId", java.util.UUID.class);

public final StringPath title = createString("title");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public class QSubmission extends EntityPathBase<Submission> {
//inherited
public final StringPath lastModifiedBy = _super.lastModifiedBy;

public final NumberPath<Long> submissionId = createNumber("submissionId", Long.class);
public final ComparablePath<java.util.UUID> submissionId = createComparable("submissionId", java.util.UUID.class);

public final DateTimePath<java.time.LocalDateTime> submittedAt = createDateTime("submittedAt", java.time.LocalDateTime.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class QSubmissionAttachment extends EntityPathBase<SubmissionAttachment>

public final QSubmission submission;

public final NumberPath<Long> SubmissionAttachmentId = createNumber("SubmissionAttachmentId", Long.class);
public final ComparablePath<java.util.UUID> SubmissionAttachmentId = createComparable("SubmissionAttachmentId", java.util.UUID.class);

public final EnumPath<fileType> type = createEnum("type", fileType.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class QUserEntity extends EntityPathBase<UserEntity> {

public final EnumPath<Role> role = createEnum("role", Role.class);

public final NumberPath<Long> userId = createNumber("userId", Long.class);
public final ComparablePath<java.util.UUID> userId = createComparable("userId", java.util.UUID.class);

public final StringPath username = createString("username");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/assignments")
Expand All @@ -40,12 +41,12 @@ public class AssignmentCommandController {
// 과제 단일 조회
@GetMapping("/{assignmentId}")
public ResponseEntity<AssignmentResponseDto> getAssignment(
@CurrentUser Long userId,
@PathVariable Long assignmentId
@CurrentUser UUID userId,
@PathVariable UUID assignmentId
) {
AssignmentResponseDto result = assignmentCommandService.findById(assignmentId);
Assignment assignment = assignmentCommandService.findByIdOrThrow(assignmentId);
Long classroomId = assignment.getClassRoom().getClassRoomId();
UUID classroomId = assignment.getClassRoom().getClassRoomId();
if (!classroomUserService.isUserInClassroom(classroomId, userId)) {
Comment on lines +44 to 50
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

인가(권한) 검증을 데이터 조회보다 먼저 수행하세요

DTO 조회를 먼저 수행하면 불필요한 DB 접근 및 정보 노출 가능성이 있습니다. 아래처럼 순서를 바꾸세요.

-    AssignmentResponseDto result = assignmentCommandService.findById(assignmentId);
-    Assignment assignment = assignmentCommandService.findByIdOrThrow(assignmentId);
+    Assignment assignment = assignmentCommandService.findByIdOrThrow(assignmentId);
     UUID classroomId = assignment.getClassRoom().getClassRoomId();
     if (!classroomUserService.isUserInClassroom(classroomId, userId)) {
       throw new AccessDeniedException("해당 수업실에 속하지 않은 유저입니다.");
     }
+    AssignmentResponseDto result = assignmentCommandService.findById(assignmentId);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@CurrentUser UUID userId,
@PathVariable UUID assignmentId
) {
AssignmentResponseDto result = assignmentCommandService.findById(assignmentId);
Assignment assignment = assignmentCommandService.findByIdOrThrow(assignmentId);
Long classroomId = assignment.getClassRoom().getClassRoomId();
UUID classroomId = assignment.getClassRoom().getClassRoomId();
if (!classroomUserService.isUserInClassroom(classroomId, userId)) {
Assignment assignment = assignmentCommandService.findByIdOrThrow(assignmentId);
UUID classroomId = assignment.getClassRoom().getClassRoomId();
if (!classroomUserService.isUserInClassroom(classroomId, userId)) {
throw new AccessDeniedException("해당 수업실에 속하지 않은 유저입니다.");
}
AssignmentResponseDto result = assignmentCommandService.findById(assignmentId);
🤖 Prompt for AI Agents
In
src/main/java/hello/cluebackend/domain/assignment/api/AssignmentCommandController.java
around lines 44 to 50, the controller currently fetches the DTO before
performing authorization which can cause unnecessary DB access and data
exposure; change the flow to first retrieve the Assignment entity (use
findByIdOrThrow), perform the classroom membership check with
classroomUserService.isUserInClassroom using
assignment.getClassRoom().getClassRoomId(), and only after the check pass either
convert that same Assignment to AssignmentResponseDto or call findById for the
DTO if conversion is nontrivial—this avoids extra DB calls and ensures
authorization is enforced before data exposure.

throw new AccessDeniedException("해당 수업실에 속하지 않은 유저입니다.");
}
Expand All @@ -55,8 +56,8 @@ public ResponseEntity<AssignmentResponseDto> getAssignment(
// 교실 과제 전체 조회
@GetMapping("/{classId}/all")
public ResponseEntity<List<AssignmentResponseDto>> getAllClassroomAssignment(
@CurrentUser Long userId,
@PathVariable Long classId
@CurrentUser UUID userId,
@PathVariable UUID classId
) {
List<AssignmentResponseDto> result = assignmentCommandService.findAllById(userId,classId);

Expand All @@ -69,23 +70,23 @@ public ResponseEntity<List<AssignmentResponseDto>> getAllClassroomAssignment(

// 메인 페이지 모든 과제 조회
@GetMapping("/me")
public ResponseEntity<List<GetAllAssignmentDto>> getAllAssignments(@CurrentUser Long userId) {
public ResponseEntity<List<GetAllAssignmentDto>> getAllAssignments(@CurrentUser UUID userId) {
List<GetAllAssignmentDto> result = assignmentCommandService.findAllAssignmentMe(userId);
return ResponseEntity.ok(result);
}

// 첨부 파일 혹은 링크 전체 조회 (선생, 학생)
@GetMapping("/{submissionId}/attachment")
public ResponseEntity<List<SubmissionAttachmentDto>> findAllAssignments(@CurrentUser Long userId, @PathVariable Long submissionId) {
public ResponseEntity<List<SubmissionAttachmentDto>> findAllAssignments(@CurrentUser UUID userId, @PathVariable UUID submissionId) {
List<SubmissionAttachmentDto> result = submissionCommandService.findAllAssignment(submissionId);
return ResponseEntity.ok(result);
}
Comment on lines 78 to 83
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

제출물 첨부 조회 엔드포인트에 인가 검증이 누락되어 있습니다

현재 사용자 검증 없이 제출물 첨부 목록을 노출합니다. 수업 멤버 또는 적법한 당사자(담당 교사/제출자)만 접근 가능하도록 확인 후 조회하세요.

예시 수정안:

   @GetMapping("/{submissionId}/attachment")
-  public ResponseEntity<List<SubmissionAttachmentDto>> findAllAssignments(@CurrentUser UUID userId, @PathVariable UUID submissionId) {
-    List<SubmissionAttachmentDto> result = submissionCommandService.findAllAssignment(submissionId);
+  public ResponseEntity<List<SubmissionAttachmentDto>> findAllAssignments(@CurrentUser UUID userId,
+                                                                          @PathVariable UUID submissionId) {
+    var submission = submissionCommandService.findByIdOrThrow(submissionId);
+    UUID classroomId = submission.getAssignment().getClassRoom().getClassRoomId();
+    if (!classroomUserService.isUserInClassroom(classroomId, userId)) {
+      throw new AccessDeniedException("해당 수업실에 속하지 않은 유저입니다.");
+    }
+    List<SubmissionAttachmentDto> result = submissionCommandService.findAllAssignment(submissionId);
     return ResponseEntity.ok(result);
   }

추가 import 필요:

import hello.cluebackend.domain.submission.domain.Submission;

또한 메서드명 findAllAssignments는 반환 타입(SubmissionAttachmentDto)에 비해 혼동됩니다. findAllSubmissionAttachments 등으로의 변경을 권장합니다.


// 첨부 파일 다운로드
@GetMapping("/{assignmentAttachmentId}/download")
public ResponseEntity<Resource> assignmentAttachmentDownload(
@CurrentUser Long userId,
@PathVariable Long assignmentAttachmentId
@CurrentUser UUID userId,
@PathVariable UUID assignmentAttachmentId
) throws IOException {
AssignmentAttachment assignmentAttachment = assignmentCommandService.findAssignmentAttachmentByIdOrderThrow(assignmentAttachmentId);
Resource resource = assignmentCommandService.downloadAttachment(assignmentAttachment);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.io.IOException;
import java.util.List;
import java.util.UUID;

@RestController
@RequestMapping("/api/assignments")
Expand All @@ -27,8 +28,8 @@ public class AssignmentQueryController {

// 과제 생성
@PostMapping
public ResponseEntity<Long> createAssignment(
@CurrentUser Long userId,
public ResponseEntity<UUID> createAssignment(
@CurrentUser UUID userId,
@Valid @RequestBody CreateAssignmentDto request
) {
Assignment assignment = assignmentQueryService.save(userId, request);
Expand All @@ -40,29 +41,29 @@ public ResponseEntity<Long> createAssignment(
// 과제 삭제
@DeleteMapping("/{assignmentId}")
public ResponseEntity<?> deleteAssignment(
@CurrentUser Long userId,
@PathVariable Long assignmentId){
@CurrentUser UUID userId,
@PathVariable UUID assignmentId){
assignmentQueryService.delete(assignmentId);
return ResponseEntity.ok("과제를 성공적으로 삭제했습니다.");
}

// 과제 수정
@PatchMapping("/{assignmentId}")
public ResponseEntity<?> modifyAssignment(
@CurrentUser Long userId,
@PathVariable Long assignmentId,
@CurrentUser UUID userId,
@PathVariable UUID assignmentId,
@Valid @RequestBody ModifyAssignmentDto assignmentDto
) {
Long assignment = assignmentQueryService.patchAssignment(assignmentId, assignmentDto);
UUID assignment = assignmentQueryService.patchAssignment(assignmentId, assignmentDto);

return ResponseEntity.ok(assignment);
}

// 첨부 파일 추가
@PostMapping("/{assignmentId}/file")
public ResponseEntity<?> uploadAttachments(
@CurrentUser Long userId,
@PathVariable Long assignmentId,
@CurrentUser UUID userId,
@PathVariable UUID assignmentId,
@RequestParam("files") MultipartFile[] files
) throws IOException {

Expand All @@ -76,8 +77,8 @@ public ResponseEntity<?> uploadAttachments(
// 첨부 링크 추가
@PostMapping("/{assignmentId}/link")
public ResponseEntity<?> urlAttachments(
@CurrentUser Long userId,
@PathVariable Long assignmentId,
@CurrentUser UUID userId,
@PathVariable UUID assignmentId,
@RequestBody List<AssignmentAttachmentDto> assignmentAttachmentDto
){
assignmentQueryService.uploadUrlAttachment(assignmentId, assignmentAttachmentDto);
Expand All @@ -87,8 +88,8 @@ public ResponseEntity<?> urlAttachments(
// 첨부파일 혹은 링크 삭제
@DeleteMapping("/attachment/{attachmentId}")
public ResponseEntity<?> deleteAttachment(
@CurrentUser Long userId,
@PathVariable Long attachmentId
@CurrentUser UUID userId,
@PathVariable UUID attachmentId
) {
assignmentQueryService.deleteAttachment(attachmentId);
return ResponseEntity.ok("과제를 성공적으로 삭제했습니다.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
import lombok.Builder;

import java.time.LocalDateTime;
import java.util.UUID;

@Builder
public record CreateAssignmentDto (
@NotNull @JsonProperty("class_id") Long classId,
@NotNull @JsonProperty("class_id") UUID classId,
@NotNull String title,
@NotNull String content,
@NotNull @JsonProperty("start_date") @JsonFormat(pattern = "yyyy-MM-dd HH:mm") LocalDateTime startDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

@Builder
public record AssignmentResponseDto(
Long assignmentId,
UUID assignmentId,
String title,
String content,
LocalDateTime startDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@
import lombok.Data;

import java.time.LocalDateTime;
import java.util.UUID;

@Data
@Builder
public class GetAllAssignmentDto {
private Long assignmentId; // 과제 아이디
private UUID assignmentId; // 과제 아이디
private String title; // 과제 제목
@JsonFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime startDate; // 과제 시작일
@JsonFormat(pattern = "yyyy-MM-dd HH:mm") private LocalDateTime endDate; // 마감일

public GetAllAssignmentDto(Long assignmentId, String title, LocalDateTime startDate, LocalDateTime endDate){
public GetAllAssignmentDto(UUID assignmentId, String title, LocalDateTime startDate, LocalDateTime endDate){
this.assignmentId = assignmentId;
this.title = title;
this.startDate = startDate;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import lombok.Data;

import java.time.LocalDateTime;
import java.util.UUID;

@Data
@Builder
public class SubmissionCheck {
private String userName;
private int classNumberGrade;
private Long submissionId;
private UUID submissionId;
private boolean isSubmitted;
private LocalDateTime submittedAt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.io.IOException;
import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
Expand All @@ -29,7 +30,7 @@ public class AssignmentCommandService{
private final FileService fileService;

// 과제 단일 조회
public AssignmentResponseDto findById(Long assignmentId) {
public AssignmentResponseDto findById(UUID assignmentId) {
Assignment a = findByIdOrThrow(assignmentId);
List<AssignmentAttachment> assignmentAttachments = assignmentAttachmentRepository.findAllByAssignment(a);

Expand All @@ -55,7 +56,7 @@ public AssignmentResponseDto findById(Long assignmentId) {
}

// 과제 전체 조회
public List<AssignmentResponseDto> findAllById(Long userId, Long classId) {
public List<AssignmentResponseDto> findAllById(UUID userId, UUID classId) {
ClassRoom classRoom = classRoomService.findById(classId).toEntity();
List<Assignment> assignments = assignmentRepository.findAllByClassRoom(classRoom);
return assignments.stream()
Expand All @@ -64,18 +65,18 @@ public List<AssignmentResponseDto> findAllById(Long userId, Long classId) {
}

// 과제 ID를 통한 조회
public Assignment findByIdOrThrow(Long assignmentId) {
public Assignment findByIdOrThrow(UUID assignmentId) {
return assignmentRepository.findById(assignmentId)
.orElseThrow(() -> new EntityNotFoundException("해당 과제를 찾을수 없습니다."));
}

public AssignmentAttachment findAssignmentAttachmentByIdOrderThrow(Long attachmentId){
public AssignmentAttachment findAssignmentAttachmentByIdOrderThrow(UUID attachmentId){
return assignmentAttachmentRepository.findById(attachmentId)
.orElseThrow(() -> new EntityNotFoundException("해당 첨부 파일을 찾을수 없습니다."));
}

// 사용자가 속한 모든 수업 과제 조회
public List<GetAllAssignmentDto> findAllAssignmentMe(Long userId) {
public List<GetAllAssignmentDto> findAllAssignmentMe(UUID userId) {
List<Assignment> assignments = assignmentRepository.getAllByUser(userId);
return assignments.stream()
.map(a -> GetAllAssignmentDto.builder()
Expand Down
Loading
Loading