dev add method link
Test Workflow / test (push) Has been cancelled

This commit is contained in:
2026-05-04 16:59:30 +07:00
parent 25b4601bfb
commit 50577b43a2
9 changed files with 175 additions and 0 deletions
@@ -27,6 +27,7 @@ import ru.soune.nocopy.entity.company.Company;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.UploadStatus;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.*;
@@ -467,6 +468,16 @@ public class ApiController {
errorData));
}
if (!entityResponse.getPermissions().get(PermissionType.DOWNLOAD)) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("fileId", entityResponse.getId());
return ResponseEntity.ok().body(new BaseResponse(20004,
MessageCode.NOT_HAVE_DOWNLOAD_PERMISSION.getCode(),
MessageCode.NOT_HAVE_DOWNLOAD_PERMISSION.getDescription(),
errorData));
}
User fileUser = userRepository.findById(entityResponse.getUserId()).orElseThrow();
User user = userRepository.findById(userId).orElseThrow();
Company companyUser = user.getCompany();
@@ -67,6 +67,8 @@ public enum MessageCode {
USER_VERIFICATIONS_NOT_FOUND(4, "Verifications not found"),
COMPLAINT_OR_LAW_CASE_IN_WORK(2, "Complaint or lawcase in work"),
NOT_VALID_STATUS(2, "Not valid status"),
PERMISSION_NOT_VALID(2, "Not valid permission"),
NOT_HAVE_DOWNLOAD_PERMISSION(2, "Not haver permission for download"),
ADMIN_USER_NOT_FOUND(4, "Verifications ,user or admin not found");
@@ -6,8 +6,10 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import java.util.List;
import java.util.Map;
@Data
@Builder
@@ -76,4 +78,7 @@ public class FileEntityRequest {
@JsonProperty("search_query")
private String searchQuery;
@JsonProperty("permissions")
private Map<String, Boolean> permissions;
}
@@ -5,8 +5,10 @@ import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import java.time.LocalDateTime;
import java.util.Map;
@Data
@Builder
@@ -42,4 +44,5 @@ public class FileEntityResponse {
private Integer checksCount;
private LocalDateTime fileUploadDate;
private String monitoring;
private Map<PermissionType, Boolean> permissions;
}
@@ -6,10 +6,13 @@ import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@Data
@@ -92,6 +95,14 @@ public class FileEntity {
@Column
private String newExtension;
@ElementCollection
@CollectionTable(name = "file_permissions",
joinColumns = @JoinColumn(name = "file_id"))
@Column(name = "allowed")
@MapKeyEnumerated(EnumType.STRING)
@MapKeyColumn(name = "permission_type")
private Map<PermissionType, Boolean> permissions = new HashMap<>();
@OneToOne(mappedBy = "file", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnore
private ImageHashEntity imageHash;
@@ -113,6 +124,15 @@ public class FileEntity {
if (this.createdAt == null) {
this.createdAt = LocalDateTime.now();
}
if (this.permissions == null) {
this.permissions = new HashMap<>();
this.permissions.put(PermissionType.DOWNLOAD, true);
// this.permissions.put(PermissionType.VIEW, true);
// this.permissions.put(PermissionType.EDIT, true);
}
this.updatedAt = LocalDateTime.now();
}
@@ -124,4 +144,29 @@ public class FileEntity {
public static void initializeCounter(int maxId) {
supportIdCounter = new AtomicInteger(maxId);
}
@Transient
public boolean hasPermission(PermissionType type) {
return permissions.getOrDefault(type, false);
}
@Transient
public void setPermission(PermissionType type, boolean allowed) {
permissions.put(type, allowed);
}
@Transient
public boolean canDownload() {
return hasPermission(PermissionType.DOWNLOAD);
}
// @Transient
// public boolean canView() {
// return hasPermission(PermissionType.VIEW);
// }
//
// @Transient
// public boolean canEdit() {
// return hasPermission(PermissionType.EDIT);
// }
}
@@ -0,0 +1,27 @@
package ru.soune.nocopy.entity.file.permission;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public enum PermissionType {
DOWNLOAD;
public static Set<String> getValidPermissionNames() {
return Arrays.stream(PermissionType.values())
.map(Enum::name)
.collect(Collectors.toSet());
}
public static Set<String> getInvalidPermissions(Map<String, Boolean> permissions) {
Set<String> validNames = getValidPermissionNames();
return permissions.keySet().stream()
.filter(key -> !validNames.contains(key))
.collect(Collectors.toSet());
}
public static boolean areAllValid(Map<String, Boolean> permissions) {
return getInvalidPermissions(permissions).isEmpty();
}
}
@@ -13,11 +13,13 @@ import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.file.*;
import ru.soune.nocopy.entity.file.*;
import ru.soune.nocopy.entity.file.moderation.ModerationLog;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity;
import ru.soune.nocopy.exception.*;
import ru.soune.nocopy.repository.*;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import ru.soune.nocopy.service.file.moderation.ModerationService;
import ru.soune.nocopy.service.file.permission.FileAccessService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.file.FileStatsService;
@@ -57,6 +59,8 @@ public class FileEntityHandler implements RequestHandler {
private final ImageHashRepository imageHashRepository;
private FileAccessService fileAccessService;
@Override
public BaseResponse handle(BaseRequest request) {
try {
@@ -96,6 +100,8 @@ public class FileEntityHandler implements RequestHandler {
return handleGetUserAppeals(request, fileRequest);
case "files_for_moderation":
return handleGetFilesForModeration(request, fileRequest);
case "change_permission":
return handleChangePermission(request, fileRequest);
default:
ActionResponse response = ActionResponse.builder()
.action(action)
@@ -160,6 +166,57 @@ public class FileEntityHandler implements RequestHandler {
}
}
private BaseResponse handleChangePermission(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = authService.useUserAuthToken(fileRequest.getToken());
FileEntityResponse fileInfo = fileEntityService.getById(fileRequest.getFileId(), request.getVersion());
if (!fileInfo.getUserId().equals(userId)) {
return new BaseResponse(request.getMsgId(),
MessageCode.ACCESS_DENIED.getCode(),
"Access denied",
null);
}
Map<String, Boolean> permissions = fileRequest.getPermissions();
if (!PermissionType.areAllValid(permissions)) {
return new BaseResponse(request.getMsgId(),
MessageCode.PERMISSION_NOT_VALID.getCode(),
MessageCode.PERMISSION_NOT_VALID.getDescription(),
null);
}
for (Map.Entry<String, Boolean> entry: permissions.entrySet()) {
try {
fileAccessService.changePermission(fileInfo.getId(), PermissionType.valueOf(entry.getKey()),
entry.getValue());
} catch (FileEntityNotFoundException e) {
return new BaseResponse(request.getMsgId(),
MessageCode.FILE_NOT_FOUND.getCode(),
MessageCode.FILE_NOT_FOUND.getDescription(),
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 = authService.useUserAuthToken(fileRequest.getToken());
@@ -416,6 +416,7 @@ public class FileEntityService {
.fileUploadDate(fileEntity.getCreatedAt())
.protectedFilePath(fileEntity.getProtectedFilePath())
.thumbnailFileUrl(baseUrl + "/api/files/protected/" + fileEntity.getId() + "/thumbnail")
.permissions(fileEntity.getPermissions())
.build();
}
}
@@ -0,0 +1,24 @@
package ru.soune.nocopy.service.file.permission;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import ru.soune.nocopy.repository.FileEntityRepository;
import java.io.FileNotFoundException;
@Service
@RequiredArgsConstructor
public class FileAccessService {
private final FileEntityRepository fileEntityRepository;
public void changePermission(String fileId, PermissionType type, boolean allowed) throws FileNotFoundException {
FileEntity file = fileEntityRepository.findById(fileId)
.orElseThrow(() -> new FileNotFoundException(fileId));
file.setPermission(type, allowed);
fileEntityRepository.save(file);
}
}