6 Commits
Author SHA1 Message Date
vladp ab3eef1668 NCBACK-25 change path to file
Test Workflow / test (push) Successful in 3s
2026-01-25 12:10:56 +07:00
vladp 63c3794aa4 fix
Test Workflow / test (push) Successful in 4s
2026-01-24 11:34:30 +07:00
vladp d638819ee9 NCBACK-25
Test Workflow / test (push) Successful in 2s
2026-01-23 13:25:56 +07:00
vladp 51654fd060 NCBACK-25 add protection for audio and use hash method from library
Test Workflow / test (push) Successful in 2s
2026-01-23 13:22:02 +07:00
vladp e37cc06cd0 NCBACK-25 add protection for audio and use hash method from library
Test Workflow / test (push) Successful in 3s
2026-01-22 20:53:25 +07:00
vladp 5a3e26b6a3 NCBACK-25 add protection for audio and use hash method from library
Test Workflow / test (push) Successful in 4s
2026-01-22 20:52:45 +07:00
19 changed files with 116 additions and 134 deletions
-10
View File
@@ -13,13 +13,6 @@ java {
} }
} }
//dependencyManagement {
// imports {
// mavenBom "org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.6.4"
// }
//}
configurations { configurations {
compileOnly { compileOnly {
extendsFrom annotationProcessor extendsFrom annotationProcessor
@@ -62,9 +55,6 @@ dependencies {
testImplementation 'org.mockito:mockito-core:5.3.1' testImplementation 'org.mockito:mockito-core:5.3.1'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher' testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.21'
// implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
// implementation 'io.insert-koin:koin-core:3.5.0'
implementation name: 'testlib-fat-0.2.1-all' implementation name: 'testlib-fat-0.2.1-all'
} }
@@ -2,6 +2,7 @@ package ru.soune.nocopy.controller;
import com.vrt.NoCopyFileService; import com.vrt.NoCopyFileService;
import com.vrt.fileprotection.FileProtector; import com.vrt.fileprotection.FileProtector;
import com.vrt.fileprotection.NoCopyCheckResult;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
@@ -38,6 +39,7 @@ import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.file.FileUploadService; import ru.soune.nocopy.service.file.FileUploadService;
import ru.soune.nocopy.util.FileUtil; import ru.soune.nocopy.util.FileUtil;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -380,6 +382,25 @@ public class ApiController {
return ResponseEntity.ok().build(); return ResponseEntity.ok().build();
} }
@GetMapping("/check/{fileId}/{type}")
public ResponseEntity<?> check(@PathVariable(required = false) String fileId,
@PathVariable(required = false) String type) {
Optional<FileEntity> optionalFileEntity = fileEntityRepository.findById(fileId);
if (!optionalFileEntity.isPresent()) {
return ResponseEntity.notFound().build();
}
FileEntity fileEntity = optionalFileEntity.get();
Path path = Paths.get(fileEntity.getProtectedFilePath());
File file = path.toFile();
NoCopyCheckResult noCopyCheckResult = noCopyFileService.checkFile(file,
FileProtector.Type.valueOf(type.toUpperCase()));
return ResponseEntity.ok().body(noCopyCheckResult);
}
private ResponseEntity<BaseResponse> checkForDuplicates(String uploadId) throws IOException { private ResponseEntity<BaseResponse> checkForDuplicates(String uploadId) throws IOException {
Optional<FileEntity> uploadedFile = fileEntityRepository.findByUploadSessionId(uploadId); Optional<FileEntity> uploadedFile = fileEntityRepository.findByUploadSessionId(uploadId);
@@ -1,49 +0,0 @@
package ru.soune.nocopy.entity;
import jakarta.persistence.*;
import lombok.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import java.time.LocalDateTime;
@Entity
@Table(name = "image_protection")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
@EntityListeners(AuditingEntityListener.class)
public class ImageProtection {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long protectionId;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
@ToString.Exclude
private User user;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "content_id", nullable = false)
@ToString.Exclude
private UserContent content;
@Column(name = "protection_method", nullable = false, length = 50)
private String protectionMethod;
@Column(name = "protection_level", nullable = false)
private Integer protectionLevel;
@Column(name = "is_active", nullable = false)
private Boolean isActive = true;
@CreatedDate
@Column(name = "applied_at", nullable = false, updatable = false)
private LocalDateTime appliedAt;
@Column(name = "metadata", columnDefinition = "JSON")
private String metadata;
}
@@ -84,10 +84,4 @@ public class User {
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnore @JsonIgnore
@ToString.Exclude @ToString.Exclude
private List<Violation> violations = new ArrayList<>(); private List<Violation> violations = new ArrayList<>();}
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
@JsonIgnore
@ToString.Exclude
private List<ImageProtection> imageProtections = new ArrayList<>();
}
@@ -10,7 +10,7 @@ public enum FileType {
IMAGE("image", Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "webp", "jfif")), IMAGE("image", Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "webp", "jfif")),
VIDEO("video", Arrays.asList("mp4", "avi", "mov", "wmv", "flv", "mkv", "webm", "m4v", "mpg", "mpeg", VIDEO("video", Arrays.asList("mp4", "avi", "mov", "wmv", "flv", "mkv", "webm", "m4v", "mpg", "mpeg",
"3gp", "3g2", "f4v", "m2ts", "mts", "vob", "ogv", "divx")), "3gp", "3g2", "f4v", "m2ts", "mts", "vob", "ogv", "divx")),
AUDIO("audio", Arrays.asList("mp3", "wav", "flac")); AUDIO("audio", List.of("wav"));
private final String displayName; private final String displayName;
private final List<String> allowedExtensions; private final List<String> allowedExtensions;
@@ -26,10 +26,10 @@ public class ImageHashEntity {
private FileEntity file; private FileEntity file;
@Column(name = "hash64_hi") @Column(name = "hash64_hi")
private Integer hash64Hi; private Long hash64Hi;
@Column(name = "hash64_lo") @Column(name = "hash64_lo")
private Integer hash64Lo; private Long hash64Lo;
@Column(name = "hash_algorithm", nullable = false) @Column(name = "hash_algorithm", nullable = false)
private String hashAlgorithm; private String hashAlgorithm;
@@ -10,5 +10,5 @@ import java.util.List;
public interface ImageHashRepository extends JpaRepository<ImageHashEntity, String> { public interface ImageHashRepository extends JpaRepository<ImageHashEntity, String> {
void deleteByFileId(String fileId); void deleteByFileId(String fileId);
List<ImageHashEntity> findByFileId(String fileId); List<ImageHashEntity> findByFileId(String fileId);
ImageHashEntity findByHash64HiAndHash64Lo(Integer hash64Hi, Integer hash64Lo); ImageHashEntity findByHash64HiAndHash64Lo(Long hash64Hi, Long hash64Lo);
} }
@@ -48,7 +48,7 @@ public interface ImageSimilarityRepository
""", """,
nativeQuery = true) nativeQuery = true)
List<SimilarImageProjection> findExactDuplicates( List<SimilarImageProjection> findExactDuplicates(
@Param("hash64Hi") Integer hash64_hi, @Param("hash64Hi") Long hash64_hi,
@Param("hash64Lo") Integer hash64_lo); @Param("hash64Lo") Long hash64_lo);
} }
@@ -1,8 +1,8 @@
package ru.soune.nocopy.repository; package ru.soune.nocopy.repository;
public interface SimilarImageProjection { public interface SimilarImageProjection {
Integer getHash64Hi(); Long getHash64Hi();
Integer getHash64Lo(); Long getHash64Lo();
String getFileId(); String getFileId();
Long getUserId(); Long getUserId();
String getOriginalFileName(); String getOriginalFileName();
@@ -32,15 +32,15 @@ public class FileSimilarityService {
var imageHashEntity = hashRepository.findById(fileId) var imageHashEntity = hashRepository.findById(fileId)
.orElseThrow(() -> new RuntimeException("Hash not found")); .orElseThrow(() -> new RuntimeException("Hash not found"));
Integer hash64Hi = imageHashEntity.getHash64Hi(); Long hash64Hi = imageHashEntity.getHash64Hi();
Integer hash64Lo = imageHashEntity.getHash64Lo(); Long hash64Lo = imageHashEntity.getHash64Lo();
List<SimilarImageProjection> candidates = repository.findCandidates(fileId); List<SimilarImageProjection> candidates = repository.findCandidates(fileId);
return candidates.stream() return candidates.stream()
.map(c -> { .map(c -> {
Integer cHi = c.getHash64Hi(); Long cHi = c.getHash64Hi();
Integer cLo = c.getHash64Lo(); Long cLo = c.getHash64Lo();
int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo);
@@ -73,13 +73,13 @@ public class FileSimilarityService {
var imageHashEntity = hashRepository.findById(fileId) var imageHashEntity = hashRepository.findById(fileId)
.orElseThrow(() -> new RuntimeException("Hash not found")); .orElseThrow(() -> new RuntimeException("Hash not found"));
Integer hash64Hi = imageHashEntity.getHash64Hi(); Long hash64Hi = imageHashEntity.getHash64Hi();
Integer hash64Lo = imageHashEntity.getHash64Lo(); Long hash64Lo = imageHashEntity.getHash64Lo();
return candidates.stream() return candidates.stream()
.map(c -> { .map(c -> {
Integer cHi = c.getHash64Hi(); Long cHi = c.getHash64Hi();
Integer cLo = c.getHash64Lo(); Long cLo = c.getHash64Lo();
int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, cHi, cLo);
@@ -112,7 +112,7 @@ public class FileSimilarityService {
.toList(); .toList();
} }
public List<SimilarImageProjection> findDuplicatedByHash(Integer hash64Hi, Integer hash64Lo) { public List<SimilarImageProjection> findDuplicatedByHash(Long hash64Hi, Long hash64Lo) {
List<SimilarImageProjection> duplicates = repository.findExactDuplicates(hash64Hi,hash64Lo); List<SimilarImageProjection> duplicates = repository.findExactDuplicates(hash64Hi,hash64Lo);
if (duplicates.isEmpty()) { if (duplicates.isEmpty()) {
@@ -126,8 +126,8 @@ public class FileSimilarityService {
var imageHashEntity = hashRepository.findById(fileId) var imageHashEntity = hashRepository.findById(fileId)
.orElseThrow(() -> new RuntimeException("Hash not found")); .orElseThrow(() -> new RuntimeException("Hash not found"));
Integer hash64Hi = imageHashEntity.getHash64Hi(); Long hash64Hi = imageHashEntity.getHash64Hi();
Integer hash64Lo = imageHashEntity.getHash64Lo(); Long hash64Lo = imageHashEntity.getHash64Lo();
List<SimilarImageProjection> candidates = repository.findCandidates(fileId); List<SimilarImageProjection> candidates = repository.findCandidates(fileId);
@@ -154,9 +154,9 @@ public class FileSimilarityService {
} }
private SimilarFileDTO createSimilarFileResponse(SimilarImageProjection similarImageProjection, private SimilarFileDTO createSimilarFileResponse(SimilarImageProjection similarImageProjection,
Integer hash64Hi, Integer hash64Lo) { Long hash64Hi, Long hash64Lo) {
Integer imageProjectionHash64Hi = similarImageProjection.getHash64Hi(); Long imageProjectionHash64Hi = similarImageProjection.getHash64Hi();
Integer similarImageProjectionHash64Lo = similarImageProjection.getHash64Lo(); Long similarImageProjectionHash64Lo = similarImageProjection.getHash64Lo();
int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, imageProjectionHash64Hi, similarImageProjectionHash64Lo); int hamming = fileUtil.hamming64(hash64Hi, hash64Lo, imageProjectionHash64Hi, similarImageProjectionHash64Lo);
@@ -22,19 +22,19 @@ public class ImageHashService {
private final ImageHashRepository repository; private final ImageHashRepository repository;
public Map<String, Integer> calculateHash(Path imagePath) throws IOException { public Map<String, Long> calculateHash(Path imagePath) throws IOException {
File file = imagePath.toFile(); File file = imagePath.toFile();
PHash pHash = PerceptualHashHelper.INSTANCE.generateDCTPerceptualHash(file); PHash pHash = PerceptualHashHelper.INSTANCE.generateDCTPerceptualHash(file);
Long firstPart = pHash.getFirstPart(); Long firstPart = pHash.getFirstPart();
Long secondPart = pHash.getSecondPart(); Long secondPart = pHash.getSecondPart();
Map<String, Integer> hash = Map.of( Map<String, Long> hash = Map.of(
"hi", Math.toIntExact(firstPart), "hi", firstPart,
"low", Math.toIntExact(secondPart)); "low", secondPart);
return hash; return hash;
} }
public void create(FileEntity file, Map<String, Integer> stringIntegerMap) { public void create(FileEntity file, Map<String, Long> stringIntegerMap) {
ImageHashEntity entity = ImageHashEntity.builder() ImageHashEntity entity = ImageHashEntity.builder()
.file(file) .file(file)
.hash64Hi(stringIntegerMap.get("hi")) .hash64Hi(stringIntegerMap.get("hi"))
@@ -12,7 +12,6 @@ import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode; import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.file.YandexSearchResponse; import ru.soune.nocopy.dto.file.YandexSearchResponse;
import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.exception.FileEntityNotFoundException;
import ru.soune.nocopy.exception.NotValidFieldException; import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.FileEntityRepository;
@@ -49,7 +49,7 @@ public class FileEntityService {
throw new IOException("File not found on disk: " + filePath); throw new IOException("File not found on disk: " + filePath);
} }
Map<String, Integer> imageHash = Map.of(); Map<String, Long> imageHash = Map.of();
if (session.getFileType().startsWith("image")) { if (session.getFileType().startsWith("image")) {
imageHash = imageHashService.calculateHash(filePath); imageHash = imageHashService.calculateHash(filePath);
@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
import ru.soune.nocopy.entity.file.FileEntity; import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.ProtectionStatus; import ru.soune.nocopy.entity.file.ProtectionStatus;
import ru.soune.nocopy.repository.FileEntityRepository; import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.util.FileUtil;
import java.util.List; import java.util.List;
@@ -21,12 +22,14 @@ public class FileProcessingOrchestrator {
private final FileEntityRepository fileRepository; private final FileEntityRepository fileRepository;
private final FileUtil fileUtil;
public void initializeProcessingQueue() { public void initializeProcessingQueue() {
List<FileEntity> filesToProtect = fileRepository.findByProtectionStatus(ProtectionStatus.NOT_PROTECTED); List<FileEntity> filesToProtect = fileRepository.findByProtectionStatus(ProtectionStatus.NOT_PROTECTED);
for (FileEntity fileEntity : filesToProtect) { for (FileEntity fileEntity : filesToProtect) {
try { try {
FileProtector.FileInfo fileInfo = createFileInfo(fileEntity); FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
noCopyFileService.addFile(fileInfo); noCopyFileService.addFile(fileInfo);
@@ -42,31 +45,9 @@ public class FileProcessingOrchestrator {
List<FileEntity> newFiles = fileRepository.findAllActiveFilesAndNotProtected(); List<FileEntity> newFiles = fileRepository.findAllActiveFilesAndNotProtected();
for (FileEntity fileEntity : newFiles) { for (FileEntity fileEntity : newFiles) {
FileProtector.FileInfo fileInfo = createFileInfo(fileEntity); FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
noCopyFileService.addFile(fileInfo); noCopyFileService.addFile(fileInfo);
} }
} }
private FileProtector.FileInfo createFileInfo(FileEntity fileEntity) {
FileProtector.Type type = determineFileType(fileEntity.getMimeType());
return new FileProtector.FileInfo(type, fileEntity.getId(), String.valueOf(fileEntity.getUserId()));
}
private FileProtector.Type determineFileType(String mimeType) {
if (mimeType == null) {
return FileProtector.Type.IMAGE;
}
if (mimeType.startsWith("image")) {
return FileProtector.Type.IMAGE;
} else if (mimeType.startsWith("video")) {
return FileProtector.Type.VIDEO;
} else if (mimeType.startsWith("audio")) {
return FileProtector.Type.AUDIO;
} else {
return FileProtector.Type.IMAGE;
}
}
} }
@@ -7,6 +7,7 @@ import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.service.file.FileEntityService; import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.util.FileUtil; import ru.soune.nocopy.util.FileUtil;
@@ -23,7 +24,9 @@ public class AudioLocalSearchImpl implements AudioLocalSearch {
@Override @Override
public @Nullable FileProtector.FileInfo findBySignature(@NotNull String signature) { public @Nullable FileProtector.FileInfo findBySignature(@NotNull String signature) {
return fileUtil.createFileInfo(fileEntityService.findBySignature(signature)); FileEntity fileEntity = fileEntityService.findBySignature(signature);
return fileUtil.createFileInfo(fileEntity);
} }
@Override @Override
@@ -1,5 +1,7 @@
package ru.soune.nocopy.service.file.impl; package ru.soune.nocopy.service.file.impl;
import com.vrt.NoCopyFileService;
import com.vrt.fileprotection.FileProtector;
import jakarta.annotation.PostConstruct; import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@@ -25,6 +27,7 @@ import ru.soune.nocopy.service.FileSimilarityService;
import ru.soune.nocopy.service.ImageHashService; import ru.soune.nocopy.service.ImageHashService;
import ru.soune.nocopy.service.file.FileEntityService; import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.file.FileUploadService; import ru.soune.nocopy.service.file.FileUploadService;
import ru.soune.nocopy.util.FileUtil;
import java.io.*; import java.io.*;
import java.nio.file.*; import java.nio.file.*;
@@ -75,6 +78,10 @@ public class FileUploadServiceImpl implements FileUploadService {
@Autowired @Autowired
private FileEntityService fileEntityService; private FileEntityService fileEntityService;
private final NoCopyFileService noCopyFileService;
private final FileUtil fileUtil;
@PostConstruct @PostConstruct
public void init() { public void init() {
try { try {
@@ -276,11 +283,16 @@ public class FileUploadServiceImpl implements FileUploadService {
FileEntity saved = fileEntityRepository.save(fileEntity); FileEntity saved = fileEntityRepository.save(fileEntity);
Map<String, Integer> hash = imageHashService.calculateHash(filePath); if (session.getFileType().equals("image")) {
Map<String, Long> hash = imageHashService.calculateHash(filePath);
imageHashService.create(saved, hash); imageHashService.create(saved, hash);
}
cleanupSessionFiles(session); cleanupSessionFiles(session);
noCopyFileService.addFile(fileUtil.createFileInfo(fileEntity));
log.info("File processing completed for session: {}", session.getUploadId()); log.info("File processing completed for session: {}", session.getUploadId());
} catch (Exception e) { } catch (Exception e) {
@@ -372,7 +384,8 @@ public class FileUploadServiceImpl implements FileUploadService {
private void checkForDuplicatesSynchronously(String filePath) private void checkForDuplicatesSynchronously(String filePath)
throws IOException { throws IOException {
Path path = Paths.get(filePath); Path path = Paths.get(filePath);
Map<String, Integer> hash = imageHashService.calculateHash(path); Map<String, Long> hash = imageHashService.calculateHash(path);
List<SimilarImageProjection> duplicates = fileSimilarityService.findDuplicatedByHash( List<SimilarImageProjection> duplicates = fileSimilarityService.findDuplicatedByHash(
hash.get("hi"), hash.get("low")); hash.get("hi"), hash.get("low"));
@@ -484,11 +497,17 @@ public class FileUploadServiceImpl implements FileUploadService {
session.setChecksum(checksum); session.setChecksum(checksum);
session.setStatus(UploadStatus.COMPLETED); session.setStatus(UploadStatus.COMPLETED);
session.setCompletedAt(LocalDateTime.now()); session.setCompletedAt(LocalDateTime.now());
sessionRepository.save(session); sessionRepository.save(session);
log.info("Upload session updated to COMPLETED: {}", session.getUploadId()); log.info("Upload session updated to COMPLETED: {}", session.getUploadId());
try { try {
fileEntityService.createFromUploadSession(session, checksum); FileEntity fileEntity = fileEntityService.createFromUploadSession(session, checksum);
FileProtector.FileInfo fileInfo = fileUtil.createFileInfo(fileEntity);
noCopyFileService.addFile(fileInfo);
log.info("FileEntity successfully created for session: {}", log.info("FileEntity successfully created for session: {}",
session.getUploadId()); session.getUploadId());
} catch (DuplicateImageException e) { } catch (DuplicateImageException e) {
@@ -44,8 +44,8 @@ public class ImageLocalSearchImpl implements ImageLocalSearch {
@Override @Override
public @Nullable FileProtector.FileInfo findByPHash(@NotNull PHash pHash) { public @Nullable FileProtector.FileInfo findByPHash(@NotNull PHash pHash) {
ImageHashEntity imageHashEntity = ImageHashEntity imageHashEntity =
imageHashRepository.findByHash64HiAndHash64Lo(Math.toIntExact(pHash.getFirstPart()), imageHashRepository.findByHash64HiAndHash64Lo(pHash.getFirstPart(),
Math.toIntExact(pHash.getSecondPart())); pHash.getSecondPart());
FileEntity file = fileEntityRepository.findByFileId(imageHashEntity.getFileId()); FileEntity file = fileEntityRepository.findByFileId(imageHashEntity.getFileId());
return new FileProtector.FileInfo(FileProtector.Type.IMAGE, imageHashEntity.getFileId(), return new FileProtector.FileInfo(FileProtector.Type.IMAGE, imageHashEntity.getFileId(),
@@ -10,12 +10,18 @@ import org.springframework.stereotype.Component;
import ru.soune.nocopy.service.file.FileEntityService; import ru.soune.nocopy.service.file.FileEntityService;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@Slf4j @Slf4j
@Component @Component
@RequiredArgsConstructor @RequiredArgsConstructor
public class ProtectionFileProviderImpl implements FileProtector.FileProvider { public class ProtectionFileProviderImpl implements FileProtector.FileProvider {
private static final Path SIGNATURE_FILE_PATH = Paths.get("/data/uploads/signature");
private final FileEntityService fileEntityService; private final FileEntityService fileEntityService;
@Nullable @Nullable
@@ -38,9 +44,32 @@ public class ProtectionFileProviderImpl implements FileProtector.FileProvider {
@Override @Override
public @Nullable File getSignature() { public @Nullable File getSignature() {
File signatureFile = SIGNATURE_FILE_PATH.toFile();
if (signatureFile.exists() && signatureFile.isFile() && signatureFile.length() > 0) {
return signatureFile;
}
return null; return null;
} }
@Override
public @NotNull OperationResult writeSignature(@NotNull byte[] bytes) {
try {
Path directory = SIGNATURE_FILE_PATH.getParent();
if (directory != null && !Files.exists(directory)) {
Files.createDirectories(directory);
}
Files.write(SIGNATURE_FILE_PATH, bytes);
return OperationResult.Companion.success();
} catch (IOException e) {
return OperationResult.Companion.failure("Not saved signature file");
}
}
@NotNull @NotNull
@Override @Override
public com.vrt.fileprotection.OperationResult writeAudioFile(@NotNull String id, @NotNull byte[] data, @Nullable String fileExt) { public com.vrt.fileprotection.OperationResult writeAudioFile(@NotNull String id, @NotNull byte[] data, @Nullable String fileExt) {
@@ -76,9 +105,4 @@ public class ProtectionFileProviderImpl implements FileProtector.FileProvider {
return OperationResult.Companion.failure("Failed to create protected file"); return OperationResult.Companion.failure("Failed to create protected file");
} }
} }
@Override
public @NotNull OperationResult writeSignature(@NotNull byte[] bytes) {
return null;
}
} }
@@ -25,9 +25,9 @@ public class FileUtil {
return new FileProtector.FileInfo(type, fileEntity.getId(), String.valueOf(fileEntity.getUserId())); return new FileProtector.FileInfo(type, fileEntity.getId(), String.valueOf(fileEntity.getUserId()));
} }
public int hamming64(int aHi, int aLo, int bHi, int bLo) { public int hamming64(long aHi, long aLo, long bHi, long bLo) {
return Integer.bitCount(aHi ^ bHi) return Long.bitCount(aHi ^ bHi)
+ Integer.bitCount(aLo ^ bLo); + Long.bitCount(aLo ^ bLo);
} }
private FileProtector.Type determineFileType(String mimeType) { private FileProtector.Type determineFileType(String mimeType) {