293 lines
12 KiB
Java
293 lines
12 KiB
Java
package ru.soune.nocopy.handler;
|
|||
|
|
|
||
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
|
|
import lombok.RequiredArgsConstructor;
|
||
|
|
import lombok.extern.slf4j.Slf4j;
|
||
|
|
import org.springframework.stereotype.Component;
|
||
|
|
import ru.soune.nocopy.dto.*;
|
||
|
|
import ru.soune.nocopy.dto.file.*;
|
||
|
|
import ru.soune.nocopy.entity.AuthToken;
|
||
|
|
import ru.soune.nocopy.exception.NotFoundAuthToken;
|
||
|
|
import ru.soune.nocopy.repository.AuthTokenRepository;
|
||
|
|
import ru.soune.nocopy.service.file.FileEntityService;
|
||
|
|
|
||
|
|
import java.util.Arrays;
|
||
|
|
|
||
|
|
@Slf4j
|
||
|
|
@Component
|
||
|
|
@RequiredArgsConstructor
|
||
|
|
public class FileEntityHandler implements RequestHandler {
|
||
|
|
|
||
|
|
private final FileEntityService fileEntityService;
|
||
|
|
private final AuthTokenRepository authTokenRepository;
|
||
|
|
private final ObjectMapper objectMapper;
|
||
|
|
|
||
|
|
@Override
|
||
|
|
public BaseResponse handle(BaseRequest request) {
|
||
|
|
try {
|
||
|
|
FileEntityRequest fileRequest = objectMapper.convertValue(
|
||
|
|
request.getMessageBody(), FileEntityRequest.class);
|
||
|
|
|
||
|
|
String action = fileRequest.getAction();
|
||
|
|
|
||
|
|
switch (action) {
|
||
|
|
case "get_file_info":
|
||
|
|
return handleGetFileInfo(request, fileRequest);
|
||
|
|
case "get_file_by_session":
|
||
|
|
return handleGetFileBySession(request, fileRequest);
|
||
|
|
case "get_user_files":
|
||
|
|
return handleGetUserFiles(request, fileRequest);
|
||
|
|
case "search_files":
|
||
|
|
return handleSearchFiles(request, fileRequest);
|
||
|
|
case "get_storage_usage":
|
||
|
|
return handleGetStorageUsage(request, fileRequest);
|
||
|
|
case "delete_file":
|
||
|
|
return handleDeleteFile(request, fileRequest);
|
||
|
|
default:
|
||
|
|
ActionResponse response = ActionResponse.builder()
|
||
|
|
.action(action)
|
||
|
|
.availableActions(Arrays.asList(
|
||
|
|
"get_file_info", "get_file_by_session", "get_user_files",
|
||
|
|
"search_files", "get_storage_usage", "delete_file"))
|
||
|
|
.build();
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_ACTION.getCode(),
|
||
|
|
"Invalid action: " + action,
|
||
|
|
response);
|
||
|
|
}
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error in FileEntityHandler", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Handler error: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleGetFileInfo(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
FileEntityResponse fileInfo = fileEntityService.getById(fileRequest.getFileId());
|
||
|
|
|
||
|
|
if (!fileInfo.getUserId().equals(userId)) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.ACCESS_DENIED.getCode(),
|
||
|
|
"Access denied",
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
MessageCode.SUCCESS.getDescription(),
|
||
|
|
fileInfo);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error getting file info", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to get file info: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleGetFileBySession(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
FileEntityResponse fileInfo = fileEntityService.getByUploadSessionId(fileRequest.getUploadSessionId());
|
||
|
|
|
||
|
|
if (!fileInfo.getUserId().equals(userId)) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.ACCESS_DENIED.getCode(),
|
||
|
|
"Access denied",
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
MessageCode.SUCCESS.getDescription(),
|
||
|
|
fileInfo);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error getting file by session", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to get file: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleGetUserFiles(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
|
||
|
|
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
|
||
|
|
|
||
|
|
FileResponse files = fileEntityService.getUserFiles(userId, page, pageSize);
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
MessageCode.SUCCESS.getDescription(),
|
||
|
|
files);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error getting user files", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to get files: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
|
||
|
|
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
|
||
|
|
|
||
|
|
if (fileRequest.getQuery() == null || fileRequest.getQuery().isBlank()) {
|
||
|
|
return handleGetUserFiles(request, fileRequest);
|
||
|
|
}
|
||
|
|
|
||
|
|
FileResponse allFiles = fileEntityService.getUserFiles(userId, 1, 1000);
|
||
|
|
|
||
|
|
var filteredFiles = allFiles.getFiles().stream()
|
||
|
|
.filter(f -> f.getOriginalFileName().toLowerCase().contains(fileRequest.getQuery().toLowerCase()))
|
||
|
|
.toList();
|
||
|
|
|
||
|
|
int start = (page - 1) * pageSize;
|
||
|
|
int end = Math.min(start + pageSize, filteredFiles.size());
|
||
|
|
|
||
|
|
FileListResponse response = FileListResponse.builder()
|
||
|
|
.files(filteredFiles.subList(start, Math.min(end, filteredFiles.size())))
|
||
|
|
.totalCount(filteredFiles.size())
|
||
|
|
.totalSize(allFiles.getTotalSize())
|
||
|
|
.formattedTotalSize(allFiles.getFormattedTotalSize())
|
||
|
|
.page(page)
|
||
|
|
.pageSize(pageSize)
|
||
|
|
.build();
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
MessageCode.SUCCESS.getDescription(),
|
||
|
|
response);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error searching files", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to search files: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleGetStorageUsage(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
long usage = fileEntityService.getUserStorageUsed(userId);
|
||
|
|
|
||
|
|
StorageUsageResponse response = StorageUsageResponse.builder()
|
||
|
|
.userId(userId)
|
||
|
|
.storageUsed(usage)
|
||
|
|
.formattedStorageUsed(formatFileSize(usage))
|
||
|
|
.build();
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
MessageCode.SUCCESS.getDescription(),
|
||
|
|
response);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error getting storage usage", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to get storage usage: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private BaseResponse handleDeleteFile(BaseRequest request, FileEntityRequest fileRequest) {
|
||
|
|
try {
|
||
|
|
Long userId = getUserIdFromToken(fileRequest.getToken());
|
||
|
|
FileEntityResponse fileInfo = fileEntityService.getById(fileRequest.getFileId());
|
||
|
|
|
||
|
|
if (!fileInfo.getUserId().equals(userId)) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.ACCESS_DENIED.getCode(),
|
||
|
|
"Access denied",
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
|
||
|
|
fileEntityService.markAsDeleted(fileRequest.getFileId());
|
||
|
|
|
||
|
|
DeleteFileResponse response = DeleteFileResponse.builder()
|
||
|
|
.fileId(fileRequest.getFileId())
|
||
|
|
.message("File marked as deleted")
|
||
|
|
.build();
|
||
|
|
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.SUCCESS.getCode(),
|
||
|
|
"File marked as deleted",
|
||
|
|
response);
|
||
|
|
|
||
|
|
} catch (NotFoundAuthToken e) {
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.INVALID_TOKEN.getCode(),
|
||
|
|
"Authentication required",
|
||
|
|
null);
|
||
|
|
} catch (Exception e) {
|
||
|
|
log.error("Error deleting file", e);
|
||
|
|
return new BaseResponse(request.getMsgId(),
|
||
|
|
MessageCode.FILE_UPLOAD_ERROR.getCode(),
|
||
|
|
"Failed to delete file: " + e.getMessage(),
|
||
|
|
null);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private Long getUserIdFromToken(String token) {
|
||
|
|
if (token == null || token.isBlank()) {
|
||
|
|
throw new NotFoundAuthToken("Token is required");
|
||
|
|
}
|
||
|
|
|
||
|
|
if (token.startsWith("Bearer ")) {
|
||
|
|
token = token.replace("Bearer ", "");
|
||
|
|
}
|
||
|
|
|
||
|
|
AuthToken authToken = authTokenRepository.findByToken(token)
|
||
|
|
.orElseThrow(() -> new NotFoundAuthToken("Token not found"));
|
||
|
|
return authToken.getUser().getId();
|
||
|
|
}
|
||
|
|
|
||
|
|
private String formatFileSize(long size) {
|
||
|
|
if (size < 1024) return size + " B";
|
||
|
|
int exp = (int) (Math.log(size) / Math.log(1024));
|
||
|
|
String pre = "KMGTPE".charAt(exp-1) + "";
|
||
|
|
return String.format("%.1f %sB", size / Math.pow(1024, exp), pre);
|
||
|
|
}
|
||
|
|
}
|