8 Commits
Author SHA1 Message Date
backdev 22e9d6c9db Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 16:07:08 +07:00
backdev 8bad5a4619 Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 15:53:03 +07:00
backdev 3b04cc8907 Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 15:39:38 +07:00
backdev ebbd69b452 Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 15:26:08 +07:00
backdev 47bed4149a Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 15:06:45 +07:00
backdev e788b062b8 Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 14:09:25 +07:00
backdev db606284cb Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-02 13:01:41 +07:00
backdev de32f9b4d1 Add file info public
Test Workflow / test (push) Has been cancelled
2026-06-01 16:56:19 +07:00
71 changed files with 1112 additions and 783 deletions
-5
View File
@@ -81,11 +81,6 @@ dependencies {
//cache
implementation("org.springframework.boot:spring-boot-starter-cache:4.0.6")
implementation 'com.github.ben-manes.caffeine:caffeine'
//security
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation("io.jsonwebtoken:jjwt:0.13.0")
}
tasks.named('test') {
@@ -26,6 +26,10 @@ import java.util.concurrent.TimeUnit;
@EnableCaching
public class ApplicationConfig {
// private final FileEntityRepository fileEntityRepository;
// private final FileUtil fileUtil;
@Bean
PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
@@ -42,6 +46,9 @@ public class ApplicationConfig {
AudioFilePathProvider audioFilePathProvider,
DocumentLocalSearch documentLocalSearch) {
// List<FileProtector.FileInfo> initialFiles = loadProcessingFile();
//TODO инициализация файлов при создании
return new com.vrt.NoCopyFileService(
Collections.emptyList(),
fileProvider,
@@ -69,5 +76,12 @@ public class ApplicationConfig {
return cacheManager;
}
// private List<FileProtector.FileInfo> loadProcessingFile() {
// List<FileEntity> byProtectionStatus =
// fileEntityRepository.findByProtectionStatus(ProtectionStatus.PROCESSING);
//
// return byProtectionStatus.stream().map(fileEntity ->
// fileUtil.createFileInfo(fileEntity, null)).toList();
// }
}
@@ -9,33 +9,14 @@ import java.util.Map;
@Configuration
public class HandlerConfig {
/*
RegRequestHandler
LoginRequestHandler
FileUploadHandler
FileEntityHandler
ImageFoundRequestHandler
VerifyRegisterUserHandler
TariffHandler
ReferralHandler
ResetPasswordHandler
MonitoringHandler
GlobalSearchHandler
ComplaintEntityHandler
ViolationNotionHandler
NotificationHandler
TokenOperationHandler
DockViewFileHandler
*/
/*
Убрать
LogoutRequestHandler logoutHandler
*/
@Bean
public Map<Integer, RequestHandler> handlers(
RegRequestHandler reg,
LoginRequestHandler login,
FileUploadHandler upload,
FileEntityHandler file,
LogoutRequestHandler logoutHandler,
ImageFoundRequestHandler imageFoundRequestHandler,
VerifyRegisterUserHandler verifyRegisterUser,
AuthRequestHandler authRequestHandler,
@@ -43,6 +24,8 @@ LogoutRequestHandler logoutHandler
TariffHandler tariffHandler,
TariffInfoHandler tariffInfoHandler,
ReferralHandler referralHandler,
ResetPasswordHandler resetPasswordHandler,
DaDataHandler daDataHandler,
PaymentHandler paymentHandler,
CostHandler costHandler,
MonitoringHandler monitoringHandler,
@@ -56,19 +39,23 @@ LogoutRequestHandler logoutHandler
UserVerificationHandler userVerificationHandler,
LawCaseHandler lawCaseHandler,
TokenOperationHandler tokenOperationHandler,
MonitoringStatisticHandler monitoringStatisticHandler,
DockViewFileHandler dockViewFileHandler
) {
Map<Integer, RequestHandler> map = new HashMap<>();
map.put(20001, login);
map.put(20002, reg);
map.put(20004, upload);
map.put(20005, file);
map.put(20006, logoutHandler);
map.put(20007, imageFoundRequestHandler);
map.put(20008, authRequestHandler);
map.put(20009, verifyRegisterUser);
map.put(20010, resetPasswordHandler);
map.put(30000, companyHandler);
map.put(30001, tariffHandler);
map.put(30002, tariffInfoHandler);
map.put(30003, referralHandler);
map.put(30004, daDataHandler);
map.put(30005, paymentHandler);
map.put(30007, monitoringHandler);
map.put(30008, costHandler);
@@ -82,7 +69,6 @@ LogoutRequestHandler logoutHandler
map.put(30016, userVerificationHandler);
map.put(30017, lawCaseHandler);
map.put(30018, tokenOperationHandler);
map.put(30027, monitoringStatisticHandler);
map.put(30028, dockViewFileHandler);
return map;
@@ -99,6 +85,7 @@ LogoutRequestHandler logoutHandler
StatisticSubscriberHandler statisticSubscriberHandler,
StatisticTokenHandler statisticTokenHandler,
StatisticIncomeHandler statisticIncomeHandler,
MonitoringStatisticHandler monitoringStatisticHandler,
FileInteranlInfoHandler fileInfo,
TariffInformationHandler tariffInformationHandler,
UserInfoHandler userInfoHandler
@@ -114,6 +101,7 @@ LogoutRequestHandler logoutHandler
map.put(30024, statisticSubscriberHandler);
map.put(30025, statisticTokenHandler);
map.put(30026, statisticIncomeHandler);
map.put(30027, monitoringStatisticHandler);
map.put(30029, statisticComplaintHandler);
map.put(40001, fileInfo);
map.put(40004, tariffInformationHandler);
@@ -137,21 +125,4 @@ LogoutRequestHandler logoutHandler
return map;
}
@Bean
public Map<Integer, RequestHandler> authHandler(
RegRequestHandler reg,
LoginRequestHandler login,
DaDataHandler daDataHandler,
ResetPasswordHandler resetPasswordHandler
)
{
Map<Integer, RequestHandler> map = new HashMap<>();
map.put(20001, login);
map.put(20002, reg);
map.put(30004, daDataHandler);
map.put(20010, resetPasswordHandler);
return map;
}
}
@@ -1,40 +0,0 @@
package ru.soune.nocopy.configuration.security;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import ru.soune.nocopy.util.JwtAuthFilter;
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthFilter jwtAuthFilter;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(AbstractHttpConfigurer::disable)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("api/v{version}/files/public-download/**").permitAll()
.requestMatchers("/api/files/public/**").permitAll()
.requestMatchers("/api/auth/**").permitAll()
.requestMatchers("/api/file/link/**").permitAll()
.requestMatchers("/check/api/**").permitAll()
.requestMatchers("/internal/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
}
@@ -5,10 +5,11 @@ import com.vrt.fileprotection.FileProtector;
import com.vrt.fileprotection.NoCopyCheckResult;
import com.vrt.fileprotection.audio.AudioCheckResult;
import com.vrt.fileprotection.documents.DocumentCheckResult;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
@@ -41,6 +42,8 @@ import ru.soune.nocopy.service.file.*;
import ru.soune.nocopy.service.file.CheckCounterService;
import ru.soune.nocopy.service.file.ProtectionsLimitService;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.util.FileUtil;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import java.io.File;
@@ -64,17 +67,17 @@ public class ApiController {
private final Map<Integer, RequestHandler> internalControlHandler;
private final Map<Integer, RequestHandler> authHandler;
private final FileEntityService fileEntityService;
private final AuthService authService;
private final FileSimilarityService fileSimilarityService;
private final FileEntityRepository fileEntityRepository;
private final NoCopyFileService noCopyFileService;
private final HttpServletRequest httpServletRequest;
private final FileUtil fileUtil;
private final ProtectionsLimitService protectionsLimitService;
@@ -131,46 +134,6 @@ public class ApiController {
}
}
@PostMapping("/auth")
public ResponseEntity<?> handlePostRequest(@RequestBody BaseRequest request) {
Integer msgId = request.getMsgId();
BaseResponse response;
try {
RequestHandler handler = authHandler.get(msgId);
if (handler == null) {
response = new BaseResponse(msgId,
MessageCode.MSG_ID_NOT_FOUND.getCode(),
MessageCode.MSG_ID_NOT_FOUND.getDescription(),
new HashMap<>());
} else {
response = handler.handle(request);
}
return ResponseEntity.ok().body(response);
} catch (ValidationException e) {
return createValidationErrorResponse(e.getBindingResult(), e.getMsgId());
} catch (UserNotFoundException e) {
return ResponseEntity.ok().body(new BaseResponse(msgId, MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(), new HashMap<>()));
} catch (NotFoundAuthToken e) {
return ResponseEntity.ok().body(new BaseResponse(msgId, MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(), new HashMap<>()));
} catch (NotValidFieldException e) {
throw e;
} catch (Exception e) {
log.error("Handler execution failed for msgId: {}", msgId, e);
BaseResponse errorResponse = new BaseResponse(msgId,
MessageCode.INVALID_JSON_BODY.getCode(),
MessageCode.INVALID_JSON_BODY.getDescription(),
new HashMap<>());
return ResponseEntity.ok().body(errorResponse);
}
}
@PostMapping("/internal/data-info")
public ResponseEntity<?> handleInternalInfoPostRequest(@RequestBody BaseRequest request) {
Integer msgId = request.getMsgId();
@@ -313,7 +276,8 @@ public class ApiController {
@RequestParam(value = "upload_id", required = false) String uploadId,
@RequestParam(value = "chunk_number", required = false) Integer chunkNumber,
@RequestParam(value = "chunk", required = false) MultipartFile chunk,
@RequestParam(value = "last_file", required = false) Boolean last_file) {
@RequestParam(value = "last_file", required = false) Boolean last_file,
@RequestParam(value = "token") String token) {
try {
if (chunk == null || chunk.isEmpty()) {
return buildErrorResponse(uploadId, chunkNumber, "Chunk file null or empty");
@@ -325,7 +289,7 @@ public class ApiController {
return buildErrorResponse(uploadId, chunkNumber, "Valid chunk number is required");
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(token);
UploadProgressResponse uploadProgressResponse = fileUploadService.uploadPassportChunk(uploadId, chunkNumber,
chunk, userId);
@@ -361,6 +325,7 @@ public class ApiController {
public ResponseEntity<BaseResponse> findSimilarFiles(
@PathVariable("version") int version,
@PathVariable String fileId,
@RequestParam(value = "auth_token", required = false) String authToken,
@RequestParam(required = false) List<String> similarityLevels,
@PageableDefault(size = 20, sort = "hammingDistance") Pageable pageable) {
@@ -372,12 +337,10 @@ public class ApiController {
MessageCode.INVALID_FIELD.getDescription(), null));
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
BaseResponse response;
if ("image".equals(fileEntity.getMimeType())) {
Page<SimilarFileDTO> similarFilesPage = fileSimilarityService.findSimilarFiles(
fileId, similarityLevels, pageable, userId);
fileId, similarityLevels, pageable, authToken);
response = buildSuccessResponse(similarFilesPage, MessageCode.SIMILAR_FILES_FOUND);
} else {
List<SimilarFileDTO> results = processNonImageFile(fileEntity, true);
@@ -625,7 +588,7 @@ public class ApiController {
errorData));
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(tokenHeader);
FileEntityResponse entityResponse = fileEntityService.getById(fileId, version);
FileStatus status = entityResponse.getStatus();
@@ -713,8 +676,8 @@ public class ApiController {
@PostMapping("/file/link")
public ResponseEntity<?> downloadFile(@RequestBody DocViewerRequest viewerRequest) {
try {
Long userId = httpServletRequest.getAttribute("userId") == null ? 0L:
(Long) httpServletRequest.getAttribute("userId");
String tokenHeader = viewerRequest.getToken();
Long userId = tokenHeader == null ? 0L: authService.useUserAuthToken(tokenHeader);
if (viewerRequest.getFileId() == null) {
return ResponseEntity.ok().body(new BaseResponse(0,
@@ -772,10 +735,14 @@ public class ApiController {
}
@GetMapping("/check/file_stats")
public ResponseEntity<?> checkFileProtectStats() {
Long userId = (Long) httpServletRequest.getAttribute("userId");
public ResponseEntity<?> checkFileProtectStats(@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
Map<String, Object> fileTypeStats = protectionsLimitService.getFileTypeStats(userId);
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
Map<String, Object> fileTypeStats = protectionsLimitService.getFileTypeStats(authToken.getUser().getId());
return ResponseEntity.ok().body(fileTypeStats);
}
@@ -11,16 +11,17 @@ import org.springframework.http.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
import ru.soune.nocopy.dto.file.CheckStatus;
import ru.soune.nocopy.dto.file.FileEntityResponse;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.ProtectionStatus;
import ru.soune.nocopy.entity.user.ProtectedFileCheck;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.file.CheckCounterService;
import ru.soune.nocopy.service.file.ZipService;
import ru.soune.nocopy.service.file.*;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import ru.soune.nocopy.util.FileUtil;
import software.amazon.awssdk.services.mq.model.NotFoundException;
import software.amazon.awssdk.services.s3.model.NoSuchKeyException;
import java.io.*;
@@ -33,12 +34,16 @@ import java.nio.charset.StandardCharsets;
@AllArgsConstructor
public class FileController {
private FileStorageService fileStorageService;
private FileEntityRepository fileRepository;
private CheckCounterService checkCounterService;
private UserRepository userRepository;
private final FileEntityService fileEntityService;
private NoCopyFileService noCopyFileService;
private FileUtil fileUtil;
@@ -85,6 +90,24 @@ public class FileController {
}
}
@GetMapping("/public/file-info/{fileId}")
public ResponseEntity<FileEntityResponse> getPublicFileInfo(@PathVariable String fileId) {
return handleGetFileInfo(fileId);
}
private ResponseEntity<FileEntityResponse> handleGetFileInfo(String fileId) {
try {
FileEntityResponse fileInfo = fileEntityService.getById(fileId, 1);
return ResponseEntity
.ok()
.body(fileInfo);
} catch (NotFoundException e) {
return ResponseEntity
.notFound().build();
}
}
private MediaType getMediaType(FileEntity fileEntity) {
try {
return MediaType.parseMediaType(fileEntity.getMimeType());
@@ -113,13 +136,6 @@ public class FileController {
String filePath = type.equals("thumbnail") ? fileEntity.getThumbnailPath(): fileEntity.getFilePath();
// InputStream file = cloudStorageService.readFileFromStorage(filePath);
// if (file == null || !file.exists()) {
// log.error("File not found in storage: {}", fileEntity.getFilePath());
// return ResponseEntity.notFound().build();
// }
if (fileEntity.getProtectionStatus() == ProtectionStatus.NOT_PROTECTED ||
fileEntity.getProtectionStatus() == ProtectionStatus.PROCESSING) {
throw new RuntimeException("File is not protected");
@@ -1,6 +1,5 @@
package ru.soune.nocopy.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
@@ -14,7 +13,9 @@ import ru.soune.nocopy.dto.violation.ViolationRequest;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.search.GlobalSearchTask;
import ru.soune.nocopy.entity.search.SearchStatus;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.repository.GlobalSearchTaskRepository;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.search.GlobalSearchService;
import ru.soune.nocopy.service.violation.ViolationService;
@@ -26,57 +27,104 @@ import java.util.*;
@RequiredArgsConstructor
public class GlobalSearchController {
private final AuthService authService;
private final GlobalSearchService globalSearchService;
private final GlobalSearchTaskRepository globalSearchTaskRepository;
private final GlobalSearchTaskRepository searchTaskRepository;
private final ViolationService violationService;
private final HttpServletRequest httpServletRequest;
@PostMapping("/start")
public ResponseEntity<?> startSearch(
@RequestBody GlobalSearchStartRequest request) {
@RequestBody GlobalSearchStartRequest request,
@RequestHeader(value = "Authorization", required = false) String tokenHeader) {
if (tokenHeader == null || tokenHeader.isBlank()) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
GlobalSearchStartResponse response = new GlobalSearchStartResponse();
Long userId = (Long) httpServletRequest.getAttribute("userId");
try {
Long userId = authService.useUserAuthToken(tokenHeader);
List<FileEntity> filesToProcess = globalSearchService.getFilesToProcess(request, userId);
List<FileEntity> filesToProcess = globalSearchService.getFilesToProcess(request, userId);
if (filesToProcess.isEmpty()) return ResponseEntity.ok().body("Files for search not found");
if (filesToProcess.isEmpty()) return ResponseEntity.ok().body("Files for search not found");
String taskId = globalSearchService.startSearch(request, userId, filesToProcess);
String taskId = globalSearchService.startSearch(request, userId, filesToProcess);
response.setTaskId(taskId);
response.setStatus(SearchStatus.ACCEPTED.name());
response.setTotalFiles(filesToProcess.size());
response.setTaskId(taskId);
response.setStatus(SearchStatus.ACCEPTED.name());
response.setTotalFiles(filesToProcess.size());
} catch (NotFoundAuthToken e) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
return ResponseEntity.ok(response);
}
@GetMapping("/actual-task")
public ResponseEntity<?> getStatus() {
public ResponseEntity<?> getStatus(@RequestHeader(value = "Authorization", required = false) String tokenHeader) {
if (tokenHeader == null || tokenHeader.isBlank()) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
Optional<GlobalSearchTask> taskOptional;
Long userId = (Long) httpServletRequest.getAttribute("userId");
try {
Long userId = authService.useUserAuthToken(tokenHeader);
taskOptional = searchTaskRepository.findByUserIdAndStatus(userId,
"PROCESSING");
taskOptional = searchTaskRepository.findByUserIdAndStatus(userId,
"PROCESSING");
if (taskOptional.isEmpty()) return ResponseEntity.ok().body("Task not found");
if (taskOptional.isEmpty()) return ResponseEntity.ok().body("Task not found");
} catch (NotFoundAuthToken e) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
return ResponseEntity.ok(taskOptional.get());
}
@GetMapping("/violation-summary")
public ResponseEntity<?> getSummary() {
public ResponseEntity<?> getSummary(@RequestHeader(value = "Authorization", required = false) String tokenHeader) {
if (tokenHeader == null || tokenHeader.isBlank()) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
List<FileViolationSummaryDTO> fileViolationsSummary;
Long userId = (Long) httpServletRequest.getAttribute("userId");
try {
Long userId = authService.useUserAuthToken(tokenHeader);
fileViolationsSummary = violationService.getFileViolationsSummary(userId);
fileViolationsSummary = violationService.getFileViolationsSummary(userId);
if (fileViolationsSummary.isEmpty()) return ResponseEntity.ok().body("Violations summary not found");
if (fileViolationsSummary.isEmpty()) return ResponseEntity.ok().body("Violations summary not found");
} catch (NotFoundAuthToken e) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
return ResponseEntity.ok(fileViolationsSummary);
}
@@ -84,32 +132,61 @@ public class GlobalSearchController {
@PostMapping("/violation-summary-with-files")
public ResponseEntity<?> getViolations(@RequestBody ViolationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Page<FileViolationSummaryDTO> result = violationService.getFileViolationsSummary(
userId, request.getFileName(), request.getSortDirection(),
request.getPage(), request.getSize(), request.getStartDate(), request.getEndDate());
if (request.getToken() == null || request.getToken().isBlank()) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", request.getToken());
return ResponseEntity.ok().body(Map.of("error", errorData));
}
return ResponseEntity.ok(result);
try {
Long userId = authService.useUserAuthToken(request.getToken());
Page<FileViolationSummaryDTO> result = violationService.getFileViolationsSummary(
userId, request.getFileName(), request.getSortDirection(),
request.getPage(), request.getSize(), request.getStartDate(), request.getEndDate());
return ResponseEntity.ok(result);
} catch (NotFoundAuthToken e) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", request.getToken());
return ResponseEntity.ok().body(Map.of("error", errorData));
}
}
@GetMapping("/status/{taskId}")
public ResponseEntity<?> getStatus(@PathVariable String taskId) {
public ResponseEntity<?> getStatus(@PathVariable String taskId,
@RequestHeader(value = "Authorization", required = false) String tokenHeader) {
if (tokenHeader == null || tokenHeader.isBlank()) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
GlobalSearchStatusResponse response;
Long userId = (Long) httpServletRequest.getAttribute("userId");
Optional<GlobalSearchTask> taskOptional = searchTaskRepository.findByTaskIdAndUserId(taskId, userId);
try {
Long userId = authService.useUserAuthToken(tokenHeader);
if (taskOptional.isEmpty()) return ResponseEntity.ok().body("Task not found");
Optional<GlobalSearchTask> taskOptional = searchTaskRepository.findByTaskIdAndUserId(taskId, userId);
GlobalSearchTask task = taskOptional.orElseThrow();
if (taskOptional.isEmpty()) return ResponseEntity.ok().body("Task not found");
int progress = task.getTotalFiles() > 0 ? task.getProcessedFiles() * 100 / task.getTotalFiles() : 0;
GlobalSearchTask task = taskOptional.orElseThrow();
response = new GlobalSearchStatusResponse();
response.setTaskId(taskId);
response.setStatus(task.getStatus());
response.setProgress(progress);
int progress = task.getTotalFiles() > 0 ? task.getProcessedFiles() * 100 / task.getTotalFiles() : 0;
response = new GlobalSearchStatusResponse();
response.setTaskId(taskId);
response.setStatus(task.getStatus());
response.setProgress(progress);
} catch (NotFoundAuthToken e) {
Map<String, Object> errorData = new HashMap<>();
errorData.put("token", tokenHeader);
return ResponseEntity.ok().body(Map.of("error", errorData));
}
return ResponseEntity.ok(response);
}
@@ -1,16 +1,17 @@
package ru.soune.nocopy.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import ru.soune.nocopy.dto.search.GlobalSearchStartResponse;
import ru.soune.nocopy.entity.payment.Payment;
import ru.soune.nocopy.exception.PaymentNotFoundException;
import ru.soune.nocopy.exception.TariffNotFoundException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.service.payment.PaymentService;
import ru.soune.nocopy.service.register.AuthService;
import java.util.HashMap;
import java.util.Map;
@@ -23,7 +24,7 @@ public class PaymentController {
private final PaymentService paymentService;
private final HttpServletRequest httpServletRequest;
private final AuthService authService;
@PostMapping("/create")
public ResponseEntity<?> createPayment(@RequestParam String email, @RequestParam Long tariffId,
@@ -68,9 +69,7 @@ public class PaymentController {
return ResponseEntity.ok().body(Map.of("error", errorData));
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
paymentService.changeAutoRenewal(userId, renewal);
paymentService.changeAutoRenewal(authService.useUserAuthToken(tokenHeader), renewal);
return ResponseEntity.ok(Map.of("message", "Auto-renewal changed:" + renewal));
} catch (UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
@@ -89,9 +88,7 @@ public class PaymentController {
return ResponseEntity.ok().body(Map.of("error", errorData));
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
paymentService.deletePaymentMethod(userId, paymentMethodId);
paymentService.deletePaymentMethod(authService.useUserAuthToken(tokenHeader), paymentMethodId);
return ResponseEntity.ok(Map.of("message", "Payment method deleted"));
} catch (UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
@@ -112,9 +109,8 @@ public class PaymentController {
return ResponseEntity.ok().body(Map.of("error", errorData));
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
return ResponseEntity.ok(paymentService.getUserPaymentMethods(userId));
return ResponseEntity.ok(paymentService.getUserPaymentMethods(
authService.useUserAuthToken(tokenHeader)));
} catch (UserNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(Map.of("error", e.getMessage()));
@@ -1,7 +1,6 @@
package ru.soune.nocopy.controller;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -13,16 +12,20 @@ import ru.soune.nocopy.entity.payout.BankTransferPayoutMethod;
import ru.soune.nocopy.entity.payout.CardPayoutMethod;
import ru.soune.nocopy.entity.payout.PayoutRequest;
import ru.soune.nocopy.entity.payout.PayoutType;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.InsufficientFundsException;
import ru.soune.nocopy.exception.InvalidPayoutMethodException;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.exception.PendingPayoutExistsException;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.payout.PayoutMethodService;
import ru.soune.nocopy.service.payout.PayoutRequestService;
import ru.soune.nocopy.service.user.UserService;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@@ -35,21 +38,21 @@ public class PayoutController {
private final PayoutMethodService payoutMethodService;
private final HttpServletRequest httpServletRequest;
private final UserService userService;
private final AuthTokenRepository authTokenRepository;
/*
Create payout
*/
@PostMapping("/create-request")
public ResponseEntity<?> createPayoutRequest(@Valid @RequestBody PayoutRequestDTO request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<?> createPayoutRequest(@RequestHeader("Authorization") String tokenHeader,
@Valid @RequestBody PayoutRequestDTO request) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body("User not found with id: " + userId);
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
try {
PayoutRequest payoutRequest = payoutRequestService.createPayoutRequest(user.getId(), request);
@@ -73,13 +76,15 @@ public class PayoutController {
Cancel payout
*/
@PostMapping("/requests/{requestId}/cancel")
public ResponseEntity<PayoutRequest> cancelPayoutRequest(@PathVariable Long requestId) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<PayoutRequest> cancelPayoutRequest(@PathVariable Long requestId,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
PayoutRequest cancelled = payoutRequestService.cancelPayoutRequest(user.getId(), requestId);
@@ -90,13 +95,14 @@ public class PayoutController {
Get user payouts
*/
@GetMapping("/requests")
public ResponseEntity<List<PayoutRequest>> getUserRequests() {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<List<PayoutRequest>> getUserRequests(@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
return ResponseEntity.ok(payoutRequestService.getUserPayoutRequests(user.getId()));
}
@@ -105,13 +111,15 @@ public class PayoutController {
Get payout by id
*/
@GetMapping("/requests/{requestId}")
public ResponseEntity<PayoutRequest> getPayoutRequest(@PathVariable Long requestId) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<PayoutRequest> getPayoutRequest(@PathVariable Long requestId,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
return ResponseEntity.ok(payoutRequestService.getPayoutRequest(user.getId(), requestId));
}
@@ -120,13 +128,14 @@ public class PayoutController {
Get payout by id
*/
@GetMapping("user/payout-methods")
public ResponseEntity<List<PayoutMethodDTO>> getUserMethods() {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<List<PayoutMethodDTO>> getUserMethods(@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
return ResponseEntity.ok(payoutMethodService.getUserMethods(user.getId()));
}
@@ -149,13 +158,15 @@ public class PayoutController {
add card method by userId
*/
@PostMapping("/payout-method/card")
public ResponseEntity<PayoutMethodDTO> addCardMethod(@Valid @RequestBody AddCardRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<PayoutMethodDTO> addCardMethod(@Valid @RequestBody AddCardRequest request,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
CardPayoutMethod method = payoutMethodService.addCardMethod(user.getId(), request);
@@ -167,13 +178,15 @@ public class PayoutController {
add bank payout-method
*/
@PostMapping("/payout-method/bank-transfer")
public ResponseEntity<PayoutMethodDTO> addBankTransferMethod(@Valid @RequestBody AddBankTransferRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<PayoutMethodDTO> addBankTransferMethod(@Valid @RequestBody AddBankTransferRequest request,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
BankTransferPayoutMethod method = payoutMethodService.addBankTransferMethod(user.getId(), request);
@@ -186,13 +199,15 @@ public class PayoutController {
set default bank payout-method
*/
@PutMapping("/payout-method/{methodId}/default")
public ResponseEntity<Void> setDefaultMethod(@PathVariable Long methodId) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<Void> setDefaultMethod(@PathVariable Long methodId,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
return ResponseEntity.notFound().build();
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
payoutMethodService.setDefaultMethod(user.getId(), methodId);
@@ -1,6 +1,5 @@
package ru.soune.nocopy.controller;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
@@ -15,19 +14,23 @@ import ru.soune.nocopy.dto.user.UserDTO;
import ru.soune.nocopy.dto.user.UserRequest;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.InvalidUserEmail;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.mapper.UserMapper;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.file.FileStatsService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.tariff.TariffService;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.util.JwtUtil;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@RestController
@RequestMapping("v1/api/user")
@@ -38,79 +41,88 @@ public class UserController {
private final UserService userService;
private final AuthTokenRepository authTokenRepository;
private final UserMapper userMapper;
private final PasswordEncoder passwordEncoder;
private final AuthService authService;
private final TariffService tariffService;
private final FileStatsService fileStatsService;
private final JwtUtil jwtUtil;
private final HttpServletRequest httpServletRequest;
@GetMapping
public ResponseEntity<UserDTO> getUser(@RequestParam("email") String email) {
User user = userRepository.findByEmail(email);
public ResponseEntity<UserDTO> getUser(@RequestParam("email") String email,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user != null) {
UserDTO userDTO = userMapper.toDTO(user);
userDTO.setEmail(email);
userDTO.setFullName(user.getFullName());
userDTO.setVerifiedStatus(user.getVerificationStatus());
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
if (user.getCompany() != null) {
userDTO.setCompany(user.getCompany().getCompanyName());
}
if (tokenOptional.isPresent()) {
User user = userRepository.findByEmail(email);
if (user.canManageCompanySettings() || user.canLogin() && user.getCompany() == null) {
userDTO.setTariffs(tariffService.getTariffByAccountType(user));
if (user != null) {
UserDTO userDTO = userMapper.toDTO(user);
userDTO.setEmail(email);
userDTO.setFullName(user.getFullName());
userDTO.setVerifiedStatus(user.getVerificationStatus());
Long fileOnDisk = user.canManageCompanySettings() ?
fileStatsService.calculateCompanyFileSize(user.getId()):
fileStatsService.calculateUserFileSize(user.getId());
Integer filesCount = user.canManageCompanySettings() ?
fileStatsService.filesCompanyCount(user.getId()):
fileStatsService.filesUserCount(user.getId());
TariffInfo personalTariffInfo;
if (user.getCompany() == null) {
personalTariffInfo = user.getPersonalTariffInfo();
} else {
personalTariffInfo = user.getCompany().getTariffInfo();
if (user.getCompany() != null) {
userDTO.setCompany(user.getCompany().getCompanyName());
}
Tariff tariff = personalTariffInfo.getTariff();
if (user.canManageCompanySettings() || user.canLogin() && user.getCompany() == null) {
userDTO.setTariffs(tariffService.getTariffByAccountType(user));
TariffInfoDTO infoDTO = TariffInfoDTO.builder().tokens(personalTariffInfo.getTokens())
.id(personalTariffInfo.getId())
.tariffName(tariff.getName())
.status(personalTariffInfo.getStatus().name())
.tariffId(tariff.getId())
.currentFileCounts(filesCount)
.maxFileCounts(tariff.getMaxFilesCount())
.currentFileOnDisk(fileOnDisk)
.maxFileOnDisk(tariff.getDiskSize())
.startTariff(personalTariffInfo.getStartTariff())
.endTariff(personalTariffInfo.getEndTariff())
.tokens(personalTariffInfo.getTokens() + personalTariffInfo.getBoughtTokens())
.build();
Long fileOnDisk = user.canManageCompanySettings() ?
fileStatsService.calculateCompanyFileSize(user.getId()):
fileStatsService.calculateUserFileSize(user.getId());
userDTO.setTariffInfo(infoDTO);
Integer filesCount = user.canManageCompanySettings() ?
fileStatsService.filesCompanyCount(user.getId()):
fileStatsService.filesUserCount(user.getId());
TariffInfo personalTariffInfo;
if (user.getCompany() == null) {
personalTariffInfo = user.getPersonalTariffInfo();
} else {
personalTariffInfo = user.getCompany().getTariffInfo();
}
Tariff tariff = personalTariffInfo.getTariff();
TariffInfoDTO infoDTO = TariffInfoDTO.builder().tokens(personalTariffInfo.getTokens())
.id(personalTariffInfo.getId())
.tariffName(tariff.getName())
.status(personalTariffInfo.getStatus().name())
.tariffId(tariff.getId())
.currentFileCounts(filesCount)
.maxFileCounts(tariff.getMaxFilesCount())
.currentFileOnDisk(fileOnDisk)
.maxFileOnDisk(tariff.getDiskSize())
.startTariff(personalTariffInfo.getStartTariff())
.endTariff(personalTariffInfo.getEndTariff())
.tokens(personalTariffInfo.getTokens() + personalTariffInfo.getBoughtTokens())
.build();
userDTO.setTariffInfo(infoDTO);
}
userDTO.setPhone(user.getPhone());
userDTO.setGenderType(user.getGenderType());
userDTO.setBirthday(user.getBirthday());
userDTO.setCreatedAt(user.getCreatedAt());
userDTO.setActive(user.isActive());
userDTO.setPermission(user.getUserPermissions());
return ResponseEntity.ok(userDTO);
}
userDTO.setPhone(user.getPhone());
userDTO.setGenderType(user.getGenderType());
userDTO.setBirthday(user.getBirthday());
userDTO.setCreatedAt(user.getCreatedAt());
userDTO.setActive(user.isActive());
userDTO.setPermission(user.getUserPermissions());
return ResponseEntity.ok(userDTO);
} else {
return ResponseEntity.notFound().build();
}
return ResponseEntity.notFound().build();
@@ -118,13 +130,15 @@ public class UserController {
//TODO fix mapper,doesnot exist all fields
@PostMapping("/change-password")
public ResponseEntity<UserDTO> updateUser(@RequestBody ChangePasswordRequest changePasswordRequest) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<UserDTO> updateUser(@RequestBody ChangePasswordRequest changePasswordRequest,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
throw new UserNotFoundException("User not found by id: " + userId);
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
if (!changePasswordRequest.getEmail().equals(user.getEmail())) {
throw new InvalidUserEmail("Email is not valid: " + changePasswordRequest.getEmail() + "not found");
@@ -136,19 +150,21 @@ public class UserController {
}
@PatchMapping("/user-update")
public ResponseEntity<UserDTO> updateUser(@RequestBody UserRequest userRequest) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
public ResponseEntity<UserDTO> updateUser(@RequestBody UserRequest userRequest,
@RequestHeader("Authorization") String tokenHeader) {
String token = tokenHeader.replace("Bearer ", "");
if (user == null) {
throw new UserNotFoundException("User not found by id: " + userId);
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
AuthToken authToken = tokenOptional.orElseThrow(() -> new NotFoundAuthToken("Token: " + token + "not found"));
User user = authToken.getUser();
return ResponseEntity.ok(userService.updateUser(userRequest, user));
}
@PostMapping("/create-user")
public ResponseEntity<?> addUser(@RequestBody RegRequest registerRequest) {
public ResponseEntity<User> addUser(@RequestBody RegRequest registerRequest) {
if (userRepository.existsByEmail(registerRequest.getEmail()) ||
userRepository.existsByPhone(registerRequest.getPhone())) {
@@ -175,11 +191,11 @@ public class UserController {
User savedUser = userRepository.save(user);
String authToken = jwtUtil.generateToken(savedUser.getId(), savedUser.getEmail());
AuthToken authToken = authService.generateAuthToken(savedUser);
return ResponseEntity.ok().body(Map.of(
"user", savedUser,
"token", authToken));
authTokenRepository.save(authToken);
return ResponseEntity.ok().body(savedUser);
}
@DeleteMapping("/delete-user/{userId}")
@@ -22,7 +22,6 @@ public enum MessageCode {
USER_NOT_VERIFIED(2, "User not verified"),
LAW_CASE_NOT_FOUND(4, "Law case not found"),
PERMISSION_NOT_FOUND(2, "Permission not found"),
INVALID_CREDENTIALS(2, "Invalid credentials"),
USER_NOT_FOUND(2, "User not found"),
LAW_CASE_ALREADY_EXIST(2, "Law case already exists"),
COMPLAINT_ALREADY_EXIST(2, "Complaint already exists"),
@@ -6,4 +6,6 @@ import lombok.Data;
@Data
public class TokenProcessRequest {
@JsonProperty("token")
private String token;
}
@@ -35,4 +35,7 @@ public class ComplaintRequest {
@JsonProperty("sort_direction")
private String sortDirection;
@JsonProperty("token")
private String token;
}
@@ -18,6 +18,7 @@ public class LawCaseRequest {
private String priority = LawCasePriority.HIGH.toString();
private String type;
private String lawyer;
private String token;
private Integer pageSize = 5;
private Integer pageNumber = 0;
private String sortBy = "updatedAt";
@@ -12,4 +12,7 @@ public class CostRequest {
@JsonProperty("count_files")
Integer countFilesForProtect;
@JsonProperty("auth_token")
String authToken;
}
@@ -10,6 +10,9 @@ public class DocViewerRequest {
@JsonProperty("file_id")
private String fileId;
@JsonProperty("token")
private String token;
@JsonProperty("ip")
private String ip;
@@ -9,4 +9,5 @@ public class AppealRequest {
private String fileId;
private String appealReason;
private String additionalInfo;
private String token;
}
@@ -40,6 +40,9 @@ public class FileEntityRequest {
@JsonProperty("page_size")
private Integer pageSize;
@JsonProperty("token")
private String token;
@JsonProperty("sort_by")
private String sortBy;
@@ -78,4 +81,10 @@ public class FileEntityRequest {
@JsonProperty("permissions")
private Map<String, Boolean> permissions;
@JsonProperty("is_appeal")
private Boolean isAppeal;
@JsonProperty("statuses")
private List<String> statuses;
}
@@ -8,6 +8,7 @@ import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.permission.PermissionType;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Data
@@ -45,4 +46,5 @@ public class FileEntityResponse {
private LocalDateTime fileUploadDate;
private String monitoring;
private Map<PermissionType, Boolean> permissions;
private List<Map<String, Object>> appealInfos;
}
@@ -36,4 +36,7 @@ public class FileListResponse {
@JsonProperty("total_size")
private Long totalSize;
@JsonProperty("statuses")
private List<String> statuses;
}
@@ -2,6 +2,7 @@ package ru.soune.nocopy.dto.file;
import lombok.Builder;
import lombok.Data;
import ru.soune.nocopy.entity.file.FileAppeal;
import ru.soune.nocopy.entity.file.FileStatus;
import java.time.LocalDateTime;
@@ -16,5 +17,5 @@ public class FileModerationInfo {
private FileStatus currentStatus;
private LocalDateTime uploadDate;
private Boolean hasActiveAppeal;
private AppealInfo activeAppeal;
private FileAppeal activeAppeal;
}
@@ -26,6 +26,9 @@ public class FileUploadRequest {
@JsonProperty("action")
private String action;
@JsonProperty("token")
private String token;
@JsonProperty("convertTo")
private String convertTo;
}
@@ -17,4 +17,7 @@ public class GetViolationsRequest {
@JsonProperty("mark_as_read")
private boolean markAsRead;
@JsonProperty("auth_token")
private String authToken;
}
@@ -14,4 +14,7 @@ public class SetMonitoringRequest {
@JsonProperty("monitoring_type")
private String monitoringType;
@JsonProperty("auth_token")
private String authToken;
}
@@ -4,4 +4,5 @@ import lombok.Data;
@Data
public class ActivateNotificationRequest {
private String authToken;
}
@@ -7,4 +7,5 @@ import java.util.List;
@Data
public class MarkAsReadRequest {
private List<Long> notificationIds;
private String authToken;
}
@@ -14,4 +14,5 @@ public class NotificationListRequest {
private String sortDirection = "DESC";
private List<NotificationType> types;
private List<NotificationStatus> statuses;
private String authToken;
}
@@ -10,6 +10,7 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@Builder
public class ReferralRequest {
private String token;
private Integer amount;
private Integer pageSize;
private Integer pageNumber;
@@ -6,6 +6,9 @@ import lombok.Data;
@Data
public class GlobalSearchStatisticsRequest {
@JsonProperty("token")
private String token;
@JsonProperty("limit")
private Integer limit = 10;
@@ -4,4 +4,5 @@ import lombok.Data;
@Data
public class MonitoringStatisticRequest {
private String authToken;
}
@@ -11,6 +11,9 @@ public class TokenOperationRequest {
@JsonProperty("action")
private String action;
@JsonProperty("token")
private String token;
@JsonProperty("operation_id")
private Long operationId;
@@ -5,6 +5,8 @@ import lombok.Data;
@Data
public class ViolationNotionRequest {
@JsonProperty("token")
private String token;
@JsonProperty("action")
private String action;
@@ -25,6 +25,9 @@ public class ViolationRequest {
@JsonProperty("action")
private String action;
@JsonProperty("token")
private String token;
@JsonProperty("file_name")
private String fileName = null;
@@ -6,6 +6,9 @@ import lombok.Data;
@Data
public class ViolationStatisticsRequest {
@JsonProperty("token")
private String token;
@JsonProperty("file_id")
private String fileId;
@@ -1,14 +1,15 @@
package ru.soune.nocopy.handler;
import jakarta.servlet.http.HttpServletRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.TokenProcessRequest;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.util.JwtUtil;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Map;
@@ -17,19 +18,20 @@ import java.util.Map;
@RequiredArgsConstructor
public class AuthRequestHandler implements RequestHandler {
private final HttpServletRequest httpServletRequest;
private final ObjectMapper objectMapper;
private final JwtUtil jwtUtil;
private final AuthService authService;
@Override
public BaseResponse handle(BaseRequest request) throws NotFoundAuthToken {
Long userId = (Long) httpServletRequest.getAttribute("userId");
String email = (String) httpServletRequest.getAttribute("email");
String token = jwtUtil.generateToken(userId, email);
TokenProcessRequest tokenProcessRequest = objectMapper.convertValue(request.getMessageBody(),
TokenProcessRequest.class);
authService.useUserAuthToken(tokenProcessRequest.getToken());
return new BaseResponse(request.getMsgId(),
MessageCode.SUCCESS.getCode(),
"Token processed successfully",
Map.of("token", token));
Map.of("token", tokenProcessRequest.getToken()));
}
}
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
@@ -22,6 +21,7 @@ import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.repository.ViolationRepository;
import ru.soune.nocopy.service.complaint.ComplaintEntityService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.service.violation.ViolationStatus;
@@ -39,20 +39,21 @@ public class ComplaintEntityHandler implements RequestHandler {
private final UserService userService;
private final AuthService authService;
private final FileEntityRepository fileEntityRepository;
private final ComplaintEntityRepository complaintEntityRepository;
private final ViolationRepository violationRepository;
private final HttpServletRequest httpServletRequest;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
Integer msgId = request.getMsgId();
ComplaintRequest complaintRequest = objectMapper.convertValue(request.getMessageBody(), ComplaintRequest.class);
String action = complaintRequest.getAction() == null ? "" : complaintRequest.getAction();
Long userId = (Long) httpServletRequest.getAttribute("userId");
String token = complaintRequest.getToken();
Long userId = authService.useUserAuthToken(token);
User user = userRepository.findById(userId).orElse(null);
if (user == null) {
@@ -60,7 +61,7 @@ public class ComplaintEntityHandler implements RequestHandler {
request.getMsgId(),
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("userId: ", userId));
Map.of("token: ", token));
}
List<String> emails = user.getCompany() == null ? List.of(user.getEmail()):
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -10,11 +9,12 @@ import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.cost.CostRequest;
import ru.soune.nocopy.dto.cost.CostResponse;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.cost.CostService;
import ru.soune.nocopy.service.user.UserService;
import java.util.Map;
import java.util.Optional;
@Slf4j
@Component
@@ -23,12 +23,10 @@ public class CostHandler implements RequestHandler {
private final CostService costService;
private final HttpServletRequest httpServletRequest;
private final AuthTokenRepository authTokenRepository;
private final ObjectMapper objectMapper;
private final UserService userService;
private final Integer MAX_FILES_FOR_CHECK = 1000;
@Override
@@ -66,17 +64,18 @@ public class CostHandler implements RequestHandler {
}
private BaseResponse handleCheckTokensForFilesProtect(CostRequest costRequest, BaseRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
String authToken = costRequest.getAuthToken();
Optional<AuthToken> token = authTokenRepository.findByToken(authToken);
if (user == null) {
return new BaseResponse(
if (token.isEmpty()) {
return new BaseResponse(
request.getMsgId(),
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("User: ", userId));
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
null);
}
User user = token.get().getUser();
Integer tokens = user.getActiveTariffInfo().getTokens();
int cost = costService.protectFileCost(costRequest.getFileType());
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -15,6 +14,7 @@ import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.service.dockview.DockViewService;
import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Arrays;
import java.util.List;
@@ -28,9 +28,9 @@ public class DockViewFileHandler implements RequestHandler {
private final FileEntityService fileEntityService;
private final ObjectMapper objectMapper;
private final AuthService authService;
private final HttpServletRequest httpServletRequest;
private final ObjectMapper objectMapper;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
@@ -55,7 +55,7 @@ public class DockViewFileHandler implements RequestHandler {
private BaseResponse handleGetHistory(BaseRequest request, DocViewerRequest docViewerRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(docViewerRequest.getToken());
List<String> fileIds = fileEntityService.getAllUserFiles(userId)
.stream()
.filter(fileEntity -> fileEntity.getMimeType().equals("document"))
@@ -94,7 +94,7 @@ public class DockViewFileHandler implements RequestHandler {
private BaseResponse handleGetViewStats(BaseRequest request, DocViewerRequest docViewerRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(docViewerRequest.getToken());
List<String> fileIds = fileEntityService.getAllUserFiles(userId)
.stream()
.filter(fileEntity -> fileEntity.getMimeType().equals("document"))
@@ -1,10 +1,12 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.*;
@@ -12,11 +14,13 @@ 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;
@@ -35,6 +39,8 @@ public class FileEntityHandler implements RequestHandler {
private final FileEntityService fileEntityService;
private final AuthService authService;
private final FileStatsService fileStatsService;
private final ObjectMapper objectMapper;
@@ -55,8 +61,6 @@ public class FileEntityHandler implements RequestHandler {
private final FileAccessService fileAccessService;
private final HttpServletRequest httpServletRequest;
@Override
public BaseResponse handle(BaseRequest request) {
try {
@@ -114,7 +118,7 @@ public class FileEntityHandler implements RequestHandler {
}
private BaseResponse handleGetFilesUserInfo(BaseRequest request, FileEntityRequest fileRequest) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
FileInfoUserResponse userFileStats = fileStatsService.getUserFileStats(userId);
return new BaseResponse(request.getMsgId(),
@@ -125,7 +129,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetFileInfo(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
FileEntityResponse fileInfo = fileEntityService.getById(fileRequest.getFileId(), request.getVersion());
if (!fileInfo.getUserId().equals(userId)) {
@@ -156,7 +160,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleChangePermission(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
FileEntityResponse fileInfo = fileEntityService.getById(fileRequest.getFileId(), request.getVersion());
if (!fileInfo.getUserId().equals(userId)) {
@@ -207,7 +211,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetFileBySession(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
FileEntityResponse fileInfo = fileEntityService.getByUploadSessionId(fileRequest.getUploadSessionId(),
request.getVersion());
@@ -239,7 +243,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetUserFiles(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
@@ -266,7 +270,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleSearchFiles(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
@@ -279,10 +283,14 @@ public class FileEntityHandler implements RequestHandler {
String[] searchTerms = searchQuery.split("\\s+");
String filterType = fileRequest.getType();
String dateFilter = fileRequest.getDateFilter();
List<String> statuses = fileRequest.getStatuses();
Boolean isAppeal = fileRequest.getIsAppeal();
List<FileEntityResponse> filteredFiles = allFiles.getFiles().stream()
.filter(f -> matchesSearch(f, searchTerms, searchQuery, filterType))
.filter(f -> matchesDateFilter(f, dateFilter))
.filter(f -> matchesStatuses(f, statuses))
.filter(f -> matchesAppeal(f, isAppeal))
.collect(Collectors.toList());
Comparator<FileEntityResponse> comparator = getComparator(sortBy, sortOrder);
@@ -309,6 +317,8 @@ public class FileEntityHandler implements RequestHandler {
.pageSize(pageSize)
.sortBy(sortBy)
.sortOrder(sortOrder.getValue())
.statuses(List.of(FileStatus.BLOCKED.name(), FileStatus.ACTIVE.name(),
FileStatus.MODERATION.name()))
.build();
return new BaseResponse(request.getMsgId(),
@@ -348,6 +358,22 @@ public class FileEntityHandler implements RequestHandler {
}
}
private boolean matchesStatuses(FileEntityResponse file, List<String> statuses) {
if (statuses == null || statuses.isEmpty()) {
return true;
}
return statuses.contains(file.getStatus().name());
}
private boolean matchesAppeal(FileEntityResponse file, Boolean isAppeal) {
if (isAppeal == null) {
return true;
}
return !file.getAppealInfos().isEmpty() == isAppeal;
}
private boolean matchesSearch(FileEntityResponse file, String[] searchTerms, String fullQuery, String type) {
String fileName = getSafeString(file.getFileName());
String originalFileName = getSafeString(file.getOriginalFileName());
@@ -505,7 +531,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetUserFilesWithSort(BaseRequest request, FileEntityRequest fileRequest,
String sortBy, SortOrder sortOrder) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
@@ -559,7 +585,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetStorageUsage(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
long usage = fileEntityService.getUserStorageUsed(userId);
StorageUsageResponse response = StorageUsageResponse.builder()
@@ -670,7 +696,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleDeleteFile(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
String fileId = fileRequest.getFileId();
FileEntityResponse fileInfo = fileEntityService.getById(fileId, request.getVersion());
DeleteFileResponse response;
@@ -760,7 +786,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleSubmitAppeal(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
AppealRequest appealRequest = AppealRequest.builder()
.fileId(fileRequest.getFileId())
@@ -789,7 +815,7 @@ public class FileEntityHandler implements RequestHandler {
private BaseResponse handleGetUserAppeals(BaseRequest request, FileEntityRequest fileRequest) {
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(fileRequest.getToken());
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 1;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
@@ -14,6 +14,7 @@ import ru.soune.nocopy.dto.file.AppealResponse;
import ru.soune.nocopy.dto.file.FileEntityRequest;
import ru.soune.nocopy.dto.file.FileModerationInfo;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.service.file.moderation.ModerationService;
import java.util.Arrays;
@@ -71,9 +72,11 @@ public class FileInteranlInfoHandler implements RequestHandler {
try {
int page = fileRequest.getPage() != null ? fileRequest.getPage() : 0;
int pageSize = fileRequest.getPageSize() != null ? fileRequest.getPageSize() : 20;
List<String> statuses = fileRequest.getStatuses() == null ? List.of(FileStatus.MODERATION.name(),
FileStatus.BLOCKED.name(), FileStatus.ACTIVE.name()): fileRequest.getStatuses();
Page<FileEntity> files = moderationService.getFilesForModeration(page, pageSize,
fileRequest.getSortOrder(), fileRequest.getSortBy());
fileRequest.getSortOrder(), fileRequest.getSortBy(), statuses, fileRequest.getIsAppeal());
List<Map<String, Object>> filesWithInfo = files.getContent().stream()
.map(file -> {
@@ -92,11 +95,8 @@ public class FileInteranlInfoHandler implements RequestHandler {
moderationInfoMap.put("hasActiveAppeal", info != null && info.getHasActiveAppeal());
if (info != null && info.getActiveAppeal() != null) {
Map<String, Object> appealInfoMap = new HashMap<>();
appealInfoMap.put("appealId", info.getActiveAppeal().getAppealId());
appealInfoMap.put("status", info.getActiveAppeal().getStatus());
appealInfoMap.put("createdAt", info.getActiveAppeal().getCreatedAt());
moderationInfoMap.put("appealInfo", appealInfoMap);
AppealResponse appealResponse = moderationService.convertToResponse(info.getActiveAppeal());
moderationInfoMap.put("appealInfo", appealResponse);
} else {
moderationInfoMap.put("appealInfo", null);
}
@@ -112,6 +112,7 @@ public class FileInteranlInfoHandler implements RequestHandler {
"totalCount", files.getTotalElements(),
"totalPages", files.getTotalPages(),
"currentPage", page,
"statuses",List.of(FileStatus.ACTIVE.name(), FileStatus.BLOCKED.name(), FileStatus.MODERATION.name()),
"pageSize", pageSize
);
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -11,11 +10,14 @@ import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.file.*;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.file.FileType;
import ru.soune.nocopy.entity.file.FileUploadSession;
import ru.soune.nocopy.exception.*;
import ru.soune.nocopy.handler.validator.FileUploadRequestValidator;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.FileUploadSessionRepository;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.file.FileUploadService;
import java.util.*;
@@ -27,14 +29,16 @@ import java.util.stream.Collectors;
public class FileUploadHandler implements RequestHandler {
private final FileUploadService fileUploadService;
private final AuthService authService;
private final AuthTokenRepository authTokenRepository;
private final FileUploadSessionRepository fileUploadSessionRepository;
private final ObjectMapper objectMapper;
private final FileUploadRequestValidator fileUploadRequestValidator;
private final HttpServletRequest httpServletRequest;
@Value("${file.storage.max-file-size}")
private long maxFileSize;
@@ -76,7 +80,16 @@ public class FileUploadHandler implements RequestHandler {
}
private BaseResponse handleInitUpload(BaseRequest request, FileUploadRequest fileRequest) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
String token = fileRequest.getToken();
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(token);
if (tokenOptional.isEmpty()) {
return new BaseResponse(request.getMsgId(), MessageCode.INVALID_TOKEN.getCode(),
MessageCode.INVALID_TOKEN.getDescription(), Map.of("token", token));
}
Long userId = authService.useUserAuthToken(token);
BindingResult bindingResult = new BeanPropertyBindingResult(fileRequest, "fileRequest");
fileUploadRequestValidator.validate(fileRequest, bindingResult);
@@ -206,6 +219,7 @@ public class FileUploadHandler implements RequestHandler {
return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(), response);
} catch (Exception e) {
log.error("Error getting file types", e);
return new BaseResponse(request.getMsgId(), MessageCode.FILE_UPLOAD_ERROR.getCode(),
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -9,8 +8,12 @@ import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.search.GlobalSearchStatisticsRequest;
import ru.soune.nocopy.dto.search.GlobalSearchStatisticsResponse;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.search.GlobalSearchStatisticsService;
import java.util.Optional;
@Slf4j
@Component
@RequiredArgsConstructor
@@ -20,17 +23,28 @@ public class GlobalSearchHandler implements RequestHandler {
private final GlobalSearchStatisticsService statisticsService;
private final HttpServletRequest httpServletRequest;
private final AuthTokenRepository authTokenRepository;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
GlobalSearchStatisticsRequest statRequest = objectMapper.convertValue(
request.getMessageBody(), GlobalSearchStatisticsRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (statRequest.getToken() == null) {
throw new IllegalArgumentException("User token is required");
}
GlobalSearchStatisticsResponse statistics = statisticsService.getStatistics(userId, statRequest.getLimit(),
statRequest.getDays());
Optional<AuthToken> tokenOptional =
authTokenRepository.findByToken(statRequest.getToken());
if (tokenOptional.isEmpty()) {
throw new IllegalArgumentException("User token is required");
}
Long userId = tokenOptional.orElseThrow().getUser().getId();
GlobalSearchStatisticsResponse statistics = statisticsService.getStatistics(
userId, statRequest.getLimit(), statRequest.getDays());
return BaseResponse.builder()
.msgId(request.getMsgId())
@@ -61,6 +61,12 @@ public class ImageFoundRequestHandler implements RequestHandler {
private final FileUploadService fileUploadService;
private final ImageHashService imageHashService;
private final ImageHashRepository imageHashRepository;
private final FileSimilarityService fileSimilarityService;
private final NoCopyFileService noCopyFileService;
@Override
@@ -2,7 +2,6 @@ package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.mail.MessagingException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
@@ -25,6 +24,7 @@ import ru.soune.nocopy.exception.TariffNotFoundException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.complaint.LawCaseService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.tariff.TariffConstants;
import ru.soune.nocopy.service.tariff.TariffInfoService;
import ru.soune.nocopy.service.violation.ViolationService;
@@ -41,6 +41,8 @@ public class LawCaseHandler implements RequestHandler {
private final LawCaseService lawCaseService;
private final AuthService authService;
private final ObjectMapper objectMapper;
private final UserRepository userRepository;
@@ -49,13 +51,11 @@ public class LawCaseHandler implements RequestHandler {
private final ViolationService violationService;
private final HttpServletRequest httpServletRequest;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
LawCaseRequest lawCaseRequest = objectMapper.convertValue(request.getMessageBody(),
LawCaseRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
Long userId = authService.useUserAuthToken(lawCaseRequest.getToken());
String action = lawCaseRequest.getAction();
return switch (action) {
@@ -6,10 +6,11 @@ import org.springframework.stereotype.Component;
import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.register.LoginAnswer;
import ru.soune.nocopy.dto.register.LoginRequest;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.util.JwtUtil;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Arrays;
import java.util.Map;
@@ -20,9 +21,9 @@ public class LoginRequestHandler implements RequestHandler {
private final UserRepository userRepository;
private final ObjectMapper objectMapper;
private final AuthService authService;
private final JwtUtil jwtUtil;
private final ObjectMapper objectMapper;
@Override
public BaseResponse handle(BaseRequest request) {
@@ -59,11 +60,14 @@ public class LoginRequestHandler implements RequestHandler {
MessageCode.PERMISSION_NOT_FOUND.getDescription(), loginAnswer);
}
String token = jwtUtil.generateToken(user.getId(), user.getEmail());
AuthToken authToken = authService.login(loginRequest);
String token = authToken.getToken();
LoginAnswer loginAnswer = new LoginAnswer();
loginAnswer.setToken(token);
authService.useUserAuthToken(token);
return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(), loginAnswer);
}
@@ -11,6 +11,8 @@ import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Objects;
import java.util.Optional;
@@ -18,6 +20,8 @@ import java.util.Optional;
@RequiredArgsConstructor
public class LogoutRequestHandler implements RequestHandler {
private final AuthService authService;
private final AuthTokenRepository authTokenRepository;
private final ObjectMapper objectMapper;
@@ -45,6 +49,9 @@ public class LogoutRequestHandler implements RequestHandler {
new LogoutRequest(logoutRequest.getEmail(), logoutRequest.getToken())));
}
authService.logout(logoutRequest.getToken());
return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), MessageCode.SUCCESS.getDescription(),
new LogOutAnswer(logoutRequest.getEmail()));
}
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -11,8 +10,11 @@ import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.monitoring.MonitoringStatusResponse;
import ru.soune.nocopy.dto.monitoring.SetMonitoringRequest;
import ru.soune.nocopy.entity.monitoring.MonitoringType;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.UserNotHavePermission;
import ru.soune.nocopy.service.monitoring.FileMonitoringService;
import ru.soune.nocopy.service.register.AuthService;
import java.io.FileNotFoundException;
import java.util.Arrays;
@@ -27,14 +29,24 @@ public class MonitoringHandler implements RequestHandler {
private final FileMonitoringService monitoringService;
private final HttpServletRequest httpServletRequest;
private final AuthService authService;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
SetMonitoringRequest setRequest = objectMapper.convertValue(
request.getMessageBody(), SetMonitoringRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
String authToken = setRequest.getAuthToken();
AuthToken userAuthToken = authService.getAuthToken(authToken);
if (authToken == null || userAuthToken == null) {
return new BaseResponse(30007, MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
Map.of("token", authToken));
}
User user = userAuthToken.getUser();
Long userId = user.getId();
String typeStr = setRequest.getMonitoringType();
MonitoringType monitoringType;
@@ -52,7 +64,7 @@ public class MonitoringHandler implements RequestHandler {
} catch (UserNotHavePermission e) {
return new BaseResponse(request.getMsgId(),
MessageCode.USER_NOT_HAD_PERMISSION.getCode(),
MessageCode.USER_NOT_HAD_PERMISSION.getDescription(), Map.of("User id: ", userId));
MessageCode.USER_NOT_HAD_PERMISSION.getDescription(), Map.of("token", authToken));
} catch (FileNotFoundException e) {
return new BaseResponse(request.getMsgId(),
MessageCode.FILE_NOT_FOUND.getCode(),
@@ -1,18 +1,20 @@
package ru.soune.nocopy.handler;
import jakarta.servlet.http.HttpServletRequest;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.statistic.MonitoringStatisticRequest;
import ru.soune.nocopy.dto.statistic.MonitoringStatisticResponse;
import ru.soune.nocopy.entity.company.Company;
import ru.soune.nocopy.entity.monitoring.MonitoringType;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.FileMonitoringRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.register.AuthService;
import java.util.List;
@@ -21,19 +23,24 @@ import java.util.List;
@RequiredArgsConstructor
public class MonitoringStatisticHandler implements RequestHandler {
private final ObjectMapper objectMapper;
private final AuthService authService;
private final FileMonitoringRepository fileMonitoringRepository;
private final UserRepository userRepository;
private final HttpServletRequest httpServletRequest;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
MonitoringStatisticRequest monitoringStatisticRequest = objectMapper.convertValue(request.getMessageBody(),
MonitoringStatisticRequest.class);
try {
Long userId = (Long) httpServletRequest.getAttribute("userId");
String authToken = monitoringStatisticRequest.getAuthToken();
Long userId = authService.useUserAuthToken(authToken);
User user = userRepository.findById(userId).orElseThrow();
Company company = user.getCompany();
List<Long> userIds = company == null ? List.of(userId) :
user.getCompany()
.getUsers()
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
@@ -15,7 +14,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
import ru.soune.nocopy.dto.notification.*;
import ru.soune.nocopy.entity.notification.Notification;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Arrays;
import java.util.List;
@@ -32,9 +31,7 @@ public class NotificationHandler implements RequestHandler {
private final ObjectMapper objectMapper;
private final HttpServletRequest httpServletRequest;
private final UserService userService;
private final AuthService authService;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
@@ -59,16 +56,7 @@ public class NotificationHandler implements RequestHandler {
case "list": {
NotificationListRequest listRequest = objectMapper.convertValue(request.getMessageBody(),
NotificationListRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
if (user == null) {
return new BaseResponse(
request.getMsgId(),
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("User:", userId));
}
User user = authService.getUser(listRequest.getAuthToken());
Page<Notification> page = notificationService.getAllNotifications(
user,
@@ -99,8 +87,7 @@ public class NotificationHandler implements RequestHandler {
case "active": {
ActivateNotificationRequest activateRequest = objectMapper.convertValue(request.getMessageBody(),
ActivateNotificationRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
User user = authService.getUser(activateRequest.getAuthToken());
List<Notification> recent = notificationService.getActiveNotifications(user);
@@ -120,8 +107,7 @@ public class NotificationHandler implements RequestHandler {
case "markRead": {
MarkAsReadRequest markRequest = objectMapper.convertValue(request.getMessageBody(),
MarkAsReadRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
User user = authService.getUser(markRequest.getAuthToken());
int updated = notificationService.markAsRead(user, markRequest.getNotificationIds());
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.soune.ReferralInvitee;
@@ -12,8 +11,8 @@ import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.referral.ReferralRequest;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.repository.AuthTokenRepository;
import java.util.List;
import java.util.Map;
@@ -25,9 +24,7 @@ public class ReferralHandler implements RequestHandler {
private final ReferralService referralService;
private final HttpServletRequest httpServletRequest;
private final UserService userService;
private final AuthTokenRepository authTokenRepository;
private final ObjectMapper mapper = new ObjectMapper();
@@ -35,28 +32,20 @@ public class ReferralHandler implements RequestHandler {
public BaseResponse handle(BaseRequest request) throws Exception {
ReferralRequest referralRequest = mapper.convertValue(request.getMessageBody(), ReferralRequest.class);
String action = referralRequest.getAction();
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
if (user == null) {
return new BaseResponse(
request.getMsgId(),
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("User: ", userId));
}
String token = referralRequest.getToken();
AuthToken authToken = authTokenRepository.findByToken(token).orElseThrow();
switch (action) {
case "refill":
return handleRefill(request, userId, referralRequest.getAmount());
return handleRefill(request, authToken.getUser().getId(), referralRequest.getAmount());
case "levels":
return handleReferralLevels(request);
case "level":
return handleUserLevel(request, userId);
return handleUserLevel(request, authToken.getUser().getId());
case "userStats" :
return handleUserStats(request, userId);
return handleUserStats(request, authToken.getUser().getId());
case "invitees":
return handleInvitees(referralRequest, request, userId);
return handleInvitees(referralRequest, request, authToken.getUser().getId());
}
return null;
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -12,17 +11,17 @@ import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.register.RegAnswer;
import ru.soune.nocopy.dto.register.RegRequest;
import ru.soune.nocopy.entity.referral.Referral;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.EmailVerificationToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.CompanyAlreadyExist;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.exception.ValidationException;
import ru.soune.nocopy.handler.validator.RegRequestValidator;
import ru.soune.nocopy.repository.ReferralJpaRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.mail.EmailService;
import ru.soune.nocopy.service.user.AdditionalInfoService;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.util.JwtUtil;
import java.util.Arrays;
import java.util.Map;
@@ -31,10 +30,12 @@ import java.util.Map;
@Component
@RequiredArgsConstructor
public class RegRequestHandler implements RequestHandler {
private final UserService userService;
private final UserRepository userRepository;
private final RegRequestValidator regRequestValidator;
private final AuthService authService;
private final ObjectMapper objectMapper;
private final EmailService emailService;
@@ -45,15 +46,11 @@ public class RegRequestHandler implements RequestHandler {
private final AdditionalInfoService additionalInfoService;
private final JwtUtil jwtUtil;
private final HttpServletRequest httpServletRequest;
@Override
public BaseResponse handle(BaseRequest request) throws ValidationException {
RegRequest regRequest = objectMapper.convertValue(request.getMessageBody(), RegRequest.class);
try {
if (userService.existsByEmailOrPhone(regRequest.getEmail(), regRequest.getPhone())) {
if (userRepository.existsByEmail(regRequest.getEmail()) || userRepository.existsByPhone(regRequest.getPhone())) {
RegAnswer regAnswer = new RegAnswer();
regAnswer.setFieldErrors(Arrays.asList(Map.of("email", regRequest.getEmail())));
regAnswer.setFieldErrors(Arrays.asList(Map.of("phone", regRequest.getPhone())));
@@ -95,16 +92,14 @@ public class RegRequestHandler implements RequestHandler {
}
boolean verified = mailVerified.equals("true");
Long createrId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.createUser(regRequest, verified, createrId);
EmailVerificationToken emailToken = emailService.createEmailVerificationToken(user);
AuthToken authToken = authService.register(regRequest, verified);
EmailVerificationToken emailToken = emailService.createEmailVerificationToken(authToken);
RegAnswer regAnswer = new RegAnswer();
if (verified) {
try {
emailService.sendVerificationEmail(user, emailToken.getToken());
emailService.sendVerificationEmail(authToken.getUser(), emailToken.getToken());
} catch (Exception e) {
return new BaseResponse(request.getMsgId(), MessageCode.SEND_EMAIL_EXCEPTION.getCode(),
MessageCode.SEND_EMAIL_EXCEPTION.getDescription(), Map.of(
@@ -116,22 +111,23 @@ public class RegRequestHandler implements RequestHandler {
regAnswer.setVerified(false);
regAnswer.setActive(false);
} else {
regAnswer.setUserId(user.getId());
regAnswer.setUserId(authToken.getUser().getId());
regAnswer.setVerified(true);
regAnswer.setActive(true);
}
String token = jwtUtil.generateToken(user.getId(), user.getEmail());
String token = authToken.getToken();
authService.useUserAuthToken(token);
regAnswer.setToken(token);
regAnswer.setUserId(user.getId());
regAnswer.setUserId(authToken.getUser().getId());
if (regRequest.getAccountType().equals("b2c")) {
referralService.onRegister(user.getId(), regRequest.getReferralLink());
referralService.onRegister(authToken.getUser().getId(), regRequest.getReferralLink());
}
additionalInfoService.additionalInfo(regRequest.getIp(), regRequest.getUserAgent(), user);
additionalInfoService.additionalInfo(regRequest.getIp(), regRequest.getUserAgent(), authToken.getUser());
return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(),
MessageCode.SUCCESS.getDescription(), regAnswer);
@@ -11,16 +11,21 @@ import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.file.ActionResponse;
import ru.soune.nocopy.dto.register.ResetPasswordRequest;
import ru.soune.nocopy.dto.register.ResetPasswordResponse;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.EmailVerificationToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.EmailVerificationTokenRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.mail.EmailService;
import ru.soune.nocopy.util.JwtUtil;
import ru.soune.nocopy.service.register.AuthService;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@Slf4j
@@ -31,13 +36,15 @@ public class ResetPasswordHandler implements RequestHandler{
private final EmailService emailService;
private final AuthService authService;
private final UserRepository userRepository;
private final EmailVerificationTokenRepository emailVerificationTokenRepository;
private final PasswordEncoder passwordEncoder;
private final AuthTokenRepository authTokenRepository;
private final JwtUtil jwtUtil;
private final PasswordEncoder passwordEncoder;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
@@ -45,19 +52,19 @@ public class ResetPasswordHandler implements RequestHandler{
ResetPasswordRequest.class);
String action = resetPasswordRequest.getAction();
User user = userRepository.findByEmail(resetPasswordRequest.getEmail());
AuthToken authToken;
if (user == null) {
throw new UserNotFoundException("User not found with email: " + resetPasswordRequest.getEmail());
}
String authToken;
switch (action) {
case "resetPassword":
authToken = jwtUtil.generateToken(user.getId(), user.getEmail());
authToken = authService.generateAuthToken(user);
EmailVerificationToken emailToken = emailService.createEmailVerificationToken(user);
EmailVerificationToken emailToken = emailService.createEmailVerificationToken(authToken);
emailService.sendResetPasswordEmail(user, emailToken.getToken());
emailService.sendResetPasswordEmail(authToken.getUser(), emailToken.getToken());
return successResponse(request, authToken, user, MessageCode.SUCCESS.getDescription());
case "confirmVerification":
@@ -71,7 +78,9 @@ public class ResetPasswordHandler implements RequestHandler{
MessageCode.INVALID_TOKEN.getDescription(), Map.of("verifyToken", verifyToken));
}
authToken = jwtUtil.generateToken(user.getId(), user.getEmail());
List<AuthToken> authTokens = authTokenRepository.findByUserId(user.getId());
authToken = authTokens.isEmpty() ? authService.generateAuthToken(user): authTokens.getFirst();
user.setPassword(passwordEncoder.encode(resetPasswordRequest.getPassword()));
user.setActive(true);
@@ -93,9 +102,9 @@ public class ResetPasswordHandler implements RequestHandler{
}
}
private BaseResponse successResponse(BaseRequest request, String authToken, User user, String message) {
private BaseResponse successResponse(BaseRequest request, AuthToken authToken, User user, String message) {
ResetPasswordResponse resetPasswordResponse = new ResetPasswordResponse();
resetPasswordResponse.setAuthToken(authToken);
resetPasswordResponse.setAuthToken(authToken.getToken());
resetPasswordResponse.setUserId(user.getId());
return new BaseResponse(request.getMsgId(), MessageCode.SUCCESS.getCode(), message, resetPasswordResponse);
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -16,7 +15,6 @@ import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.tariff.TariffService;
import ru.soune.nocopy.service.user.UserService;
import java.util.List;
import java.util.Map;
@@ -30,9 +28,7 @@ public class TariffHandler implements RequestHandler {
private final TariffService tariffService;
private final UserService userService;
private final HttpServletRequest httpServletRequest;
private final AuthTokenRepository authTokenRepository;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
@@ -132,16 +128,8 @@ public class TariffHandler implements RequestHandler {
}
private BaseResponse handleGetTariffs(BaseRequest request, TariffRequest tariffRequest) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
User user = userService.getUserById(userId).orElse(null);
if (user == null) {
return new BaseResponse(
request.getMsgId(),
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("User:", userId));
}
AuthToken authToken = authTokenRepository.findByToken(tariffRequest.getUserToken()).orElseThrow();
User user = authToken.getUser();
if (tariffRequest.getTariffTerm() == null || !TariffTimeTerm.validTerms().contains(
tariffRequest.getTariffTerm())) {
@@ -74,7 +74,7 @@ public class TariffInfoHandler implements RequestHandler {
private BaseResponse handleCreateTariffInfo(BaseRequest request, TariffInfoRequest tariffInfoRequest) {
try {
Long tariffId = tariffInfoRequest.getTariffId();
Tariff tariff = tariffRepository.findById(tariffId).orElseThrow();
Tariff tariff= tariffRepository.findById(tariffId).orElseThrow();
TariffTimeTerm tariffTerm = tariff.getTariffTerm();
LocalDateTime endDateTime = LocalDateTime.now().plusDays(tariffTerm.getDays());
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
@@ -13,6 +12,7 @@ import ru.soune.nocopy.dto.tokenoperation.TokenOperationPageDto;
import ru.soune.nocopy.dto.tokenoperation.TokenOperationRequest;
import ru.soune.nocopy.entity.tokenoperation.OperationType;
import ru.soune.nocopy.entity.tokenoperation.TokenOperation;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.tokenoperation.TokenOperationService;
import java.util.HashMap;
@@ -26,7 +26,7 @@ public class TokenOperationHandler implements RequestHandler {
private final ObjectMapper objectMapper;
private final HttpServletRequest httpServletRequest;
private final AuthService authService;
@Override
public BaseResponse handle(BaseRequest request) throws Exception {
@@ -91,7 +91,16 @@ public class TokenOperationHandler implements RequestHandler {
}
private BaseResponse handleGetList(Integer msgId, TokenOperationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (request.getToken() == null) {
return new BaseResponse(
msgId,
MessageCode.USER_NOT_FOUND.getCode(),
MessageCode.USER_NOT_FOUND.getDescription(),
Map.of("error", "User ID is required")
);
}
Long userId = authService.useUserAuthToken(request.getToken());
try {
Page<TokenOperation> page = tokenOperationService.findByUserId(
@@ -180,7 +189,16 @@ public class TokenOperationHandler implements RequestHandler {
}
private BaseResponse handleCreate(Integer msgId, TokenOperationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (request.getToken() == null) {
return new BaseResponse(
msgId,
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
Map.of("error", "User ID is required")
);
}
Long userId = authService.useUserAuthToken(request.getToken());
try {
TokenOperation operation = tokenOperationService.create(
@@ -298,7 +316,16 @@ public class TokenOperationHandler implements RequestHandler {
}
private BaseResponse handleDeleteAllByUser(Integer msgId, TokenOperationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (request.getToken() == null) {
return new BaseResponse(
msgId,
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
Map.of("error", "User ID is required")
);
}
Long userId = authService.useUserAuthToken(request.getToken());
try {
tokenOperationService.deleteByUserId(userId);
@@ -323,7 +350,16 @@ public class TokenOperationHandler implements RequestHandler {
}
private BaseResponse handleGetStats(Integer msgId, TokenOperationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (request.getToken() == null) {
return new BaseResponse(
msgId,
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
Map.of("error", "User ID is required")
);
}
Long userId = authService.useUserAuthToken(request.getToken());
if (userId == null) {
return new BaseResponse(
@@ -369,7 +405,16 @@ public class TokenOperationHandler implements RequestHandler {
}
private BaseResponse handleFilter(Integer msgId, TokenOperationRequest request) {
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (request.getToken() == null) {
return new BaseResponse(
msgId,
MessageCode.AUTH_TOKEN_NOT_FOUND.getCode(),
MessageCode.AUTH_TOKEN_NOT_FOUND.getDescription(),
Map.of("error", "User ID is required")
);
}
Long userId = authService.useUserAuthToken(request.getToken());
try {
Page<TokenOperation> page = tokenOperationService.findByFilters(
@@ -10,18 +10,22 @@ import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.register.RegAnswer;
import ru.soune.nocopy.dto.register.VerifyUserRequest;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.EmailVerificationToken;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.repository.EmailVerificationTokenRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.mail.EmailService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.user.UserService;
import ru.soune.nocopy.util.JwtUtil;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@Component
@Slf4j
@@ -37,7 +41,9 @@ public class VerifyRegisterUserHandler implements RequestHandler {
private final UserService userService;
private final JwtUtil jwtUtil;
private final AuthTokenRepository authTokenRepository;
private final AuthService authService;
@Override
public BaseResponse handle(BaseRequest request) throws MessagingException, IOException {
@@ -48,37 +54,45 @@ public class VerifyRegisterUserHandler implements RequestHandler {
User user = userRepository.findById(userId)
.orElseThrow(() -> new UserNotFoundException("User not found with id: " + userId));
if (verifyUserRequest.getResend() != null && verifyUserRequest.getResend() == 1) {
return handleResend(request, user);
}
List<AuthToken> userAuthTokens = authTokenRepository.findByUserId(userId);
String authToken = jwtUtil.generateToken(user.getId(), user.getEmail());
AuthToken authToken = userAuthTokens.isEmpty() ? authService.generateAuthToken(user): userAuthTokens.getFirst();
if (verifyUserRequest.getResend() != null && verifyUserRequest.getResend() == 1) {
return handleResend(request, user, authToken);
}
return handleVerify(request, user, authToken, verifyUserRequest.getVerifyToken());
}
private BaseResponse handleResend(BaseRequest request, User user) throws MessagingException, IOException {
private BaseResponse handleResend(BaseRequest request, User user, AuthToken authToken) throws MessagingException, IOException {
EmailVerificationToken token = emailVerificationTokenRepository.findByUserId(user.getId());
// if (token != null && !token.isExpired()) {
// emailService.sendVerificationEmail(user, token.getToken());
//
// log.info("Verification token resent for user {}", user.getEmail());
// return successResponse(request, authToken, "Verification code has been resent", false,
// false, user.getEmail());
// }
if (token != null) {
emailVerificationTokenRepository.delete(token);
}
EmailVerificationToken newToken = emailService.createEmailVerificationToken(user);
EmailVerificationToken newToken = emailService.createEmailVerificationToken(authToken);
emailService.sendVerificationEmail(user, newToken.getToken());
log.info("New verification token generated for user {}", user.getEmail());
String authToken = jwtUtil.generateToken(user.getId(), user.getEmail());
return successResponse(request, authToken, "New verification code has been sent",
false, false, user.getEmail());
}
private BaseResponse handleVerify(BaseRequest request, User user, String authToken, String providedToken) {
private BaseResponse handleVerify(BaseRequest request, User user, AuthToken authToken, String providedToken) {
EmailVerificationToken token = emailVerificationTokenRepository.findByUserIdAndToken(user.getId(), providedToken);
@@ -96,10 +110,10 @@ public class VerifyRegisterUserHandler implements RequestHandler {
updateUser.isEmailVerified(), updateUser.getEmail());
}
private BaseResponse successResponse(BaseRequest request, String authToken, String message, boolean isActive,
private BaseResponse successResponse(BaseRequest request, AuthToken authToken, String message, boolean isActive,
boolean isVerified, String email) {
RegAnswer regAnswer = new RegAnswer();
regAnswer.setToken(authToken);
regAnswer.setToken(authToken.getToken());
regAnswer.setVerified(isVerified);
regAnswer.setActive(isActive);
regAnswer.setEmail(email);
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
@@ -18,6 +17,7 @@ import ru.soune.nocopy.service.complaint.ComplaintEntityService;
import ru.soune.nocopy.service.complaint.LawCaseService;
import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.geo.GeoCountryService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.violation.ViolationService;
import ru.soune.nocopy.service.violation.ViolationStatus;
@@ -40,6 +40,8 @@ public class ViolationHandler implements RequestHandler {
private final FileEntityRepository fileRepository;
private final AuthService authService;
private final FileEntityService fileEntityService;
private final GeoCountryService geoCountryService;
@@ -48,8 +50,6 @@ public class ViolationHandler implements RequestHandler {
private final ComplaintEntityService complaintEntityService;
private final HttpServletRequest httpServletRequest;
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@Override
@@ -57,7 +57,9 @@ public class ViolationHandler implements RequestHandler {
ViolationRequest violationRequest = objectMapper.convertValue(request.getMessageBody(), ViolationRequest.class);
validateRequest(violationRequest);
Long userId = (Long) httpServletRequest.getAttribute("userId");
String token = violationRequest.getToken();
Long userId = authService.useUserAuthToken(token);
List<FileEntity> targetFiles;
@@ -133,6 +135,23 @@ public class ViolationHandler implements RequestHandler {
.messageBody(groupedData)
.build();
} else {
// Page<Violation> violationPage;
//
// if (startDate != null && endDate != null) {
// violationPage = violationService.getViolationsByFilesAndDateRange(
// targetFiles, startDate, endDate,
// violationRequest.getPage(), violationRequest.getSize(), violationRequest.getSortDirection()
// );
// } else if (violationRequest.getStatus() != null && !violationRequest.getStatus().isEmpty()) {
// violationPage = violationService.getViolationsByFilesAndStatus(
// targetFiles, violationRequest.getStatus(),
// violationRequest.getPage(), violationRequest.getSize(), violationRequest.getSortDirection()
// );
// } else {
// violationPage = violationService.getViolationsByFiles(
// targetFiles, violationRequest.getPage(), violationRequest.getSize(),
// violationRequest.getSortDirection());
// }
Page<Violation> violationPage = violationService.getViolationsByFilesAndFilters(
targetFiles,
startDate,
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -9,9 +8,12 @@ import ru.soune.nocopy.dto.BaseRequest;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.violation.*;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.violation.ViolationNotionService;
import java.util.List;
import java.util.Optional;
@Slf4j
@Component
@@ -21,7 +23,7 @@ public class ViolationNotionHandler implements RequestHandler {
private final ViolationNotionService notionService;
private final HttpServletRequest httpServletRequest;
private final AuthTokenRepository authTokenRepository;
@Override
public BaseResponse handle(BaseRequest request) {
@@ -29,7 +31,24 @@ public class ViolationNotionHandler implements RequestHandler {
ViolationNotionRequest notionRequest = objectMapper.convertValue(
request.getMessageBody(), ViolationNotionRequest.class);
Long userId = (Long) httpServletRequest.getAttribute("userId");
if (notionRequest.getToken() == null) {
return new BaseResponse(
request.getMsgId(),
MessageCode.INVALID_TOKEN.getCode(),
"Token is required",
"field: token");
}
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(notionRequest.getToken());
if (tokenOptional.isEmpty()) {
return new BaseResponse(
request.getMsgId(),
MessageCode.INVALID_TOKEN.getCode(),
"Invalid token",
notionRequest.getToken());
}
Long userId = tokenOptional.get().getUser().getId();
String action = notionRequest.getAction();
if (action == null || action.trim().isEmpty()) {
@@ -1,7 +1,6 @@
package ru.soune.nocopy.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -10,13 +9,16 @@ import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import ru.soune.nocopy.dto.violation.ViolationStatisticsRequest;
import ru.soune.nocopy.dto.violation.ViolationStatisticsResponse;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.exception.FileEntityNotFoundException;
import ru.soune.nocopy.exception.UserNotHavePermission;
import ru.soune.nocopy.repository.AuthTokenRepository;
import ru.soune.nocopy.service.violation.ViolationService;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Optional;
@Slf4j
@Component
@@ -26,7 +28,7 @@ public class ViolationStatisticsHandler implements RequestHandler {
private final ViolationService violationService;
private final HttpServletRequest httpServletRequest;
private final AuthTokenRepository authTokenRepository;
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -35,6 +37,8 @@ public class ViolationStatisticsHandler implements RequestHandler {
ViolationStatisticsRequest statRequest = objectMapper.convertValue(request.getMessageBody(),
ViolationStatisticsRequest.class);
validateRequest(statRequest);
LocalDateTime startDate = null;
LocalDateTime endDate = null;
@@ -47,7 +51,13 @@ public class ViolationStatisticsHandler implements RequestHandler {
}
}
Long userId = (Long) httpServletRequest.getAttribute("userId");
Optional<AuthToken> tokenOptional = authTokenRepository.findByToken(statRequest.getToken());
if (tokenOptional.isEmpty()) {
throw new IllegalArgumentException("User token is required");
}
Long userId = tokenOptional.orElseThrow().getUser().getId();
ViolationStatisticsResponse statistics;
try {
@@ -81,6 +91,12 @@ public class ViolationStatisticsHandler implements RequestHandler {
.build();
}
private void validateRequest(ViolationStatisticsRequest request) {
if (request.getToken() == null) {
throw new IllegalArgumentException("Token is required");
}
}
private LocalDateTime parseDate(String dateStr) {
try {
return LocalDateTime.parse(dateStr, DATE_FORMATTER);
@@ -84,4 +84,8 @@ public class FileUploadRequestValidator implements Validator {
"Invalid file type. Valid types: " + Arrays.toString(FileType.values()));
}
}
private String getFileExtension(String fileName) {
return fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
}
}
@@ -76,6 +76,13 @@ public interface FileEntityRepository extends JpaRepository<FileEntity, String>
Page<FileEntity> findByStatusIn(List<FileStatus> statuses, Pageable pageable);
@Query("SELECT f FROM FileEntity f WHERE f.status IN :statuses")
Page<FileEntity> findByStatusInAndSorted(@Param("statuses") List<String> statuses, Pageable pageable);
@Query("SELECT f FROM FileEntity f JOIN FileAppeal fa ON fa.fileId = f.id WHERE f.status IN :statuses")
Page<FileEntity> findByStatusInAndSortedWithAppeal(@Param("statuses") List<String> statuses, Pageable pageable);
List<FileEntity> findByUserIdAndStatusIn(Long userId, List<FileStatus> statuses);
@Query("SELECT f FROM FileEntity f WHERE f.userId = :userId AND f.status IN :statuses")
@@ -20,6 +20,7 @@ import ru.soune.nocopy.repository.*;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import ru.soune.nocopy.util.FileUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
@@ -37,6 +38,8 @@ public class FileSimilarityService {
private final FileUtil fileUtil;
private final AuthTokenRepository authTokenRepository;
private final FileEntityRepository fileEntityRepository;
private final CloudStorageService cloudStorageService;
@@ -146,7 +149,7 @@ public class FileSimilarityService {
String fileId,
List<String> similarityLevels,
Pageable pageable,
Long userId) {
String authToken) {
try {
var imageHashEntity = hashRepository.findById(fileId)
@@ -156,6 +159,7 @@ public class FileSimilarityService {
List<Long> userIds;
List<SimilarImageProjection> candidates = repository.findCandidates(fileId);
Long userId = authTokenRepository.findUserIdByToken(authToken);
User user = userRepository.findById(userId).orElseThrow(() -> new RuntimeException("User not found"));
Company company = user.getCompany();
@@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.file.FileEntityResponse;
import ru.soune.nocopy.dto.file.FileResponse;
import ru.soune.nocopy.entity.file.FileAppeal;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.entity.file.FileStatus;
import ru.soune.nocopy.entity.file.ProtectionStatus;
@@ -16,11 +17,13 @@ import ru.soune.nocopy.entity.monitoring.FileMonitoringEntity;
import ru.soune.nocopy.entity.monitoring.MonitoringType;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.FileEntityNotFoundException;
import ru.soune.nocopy.repository.FileAppealRepository;
import ru.soune.nocopy.repository.FileEntityRepository;
import ru.soune.nocopy.repository.FileMonitoringRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
@@ -29,9 +32,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@@ -47,6 +48,8 @@ public class FileEntityService {
private final CloudStorageService cloudStorageService;
private final FileAppealRepository fileAppealRepository;
@Value("${server.baseurl}")
private String baseUrl;
@@ -387,6 +390,8 @@ public class FileEntityService {
name = fileName.substring(0, lastDotIndex);
}
List<Map<String, Object>> appeals = getFileAppeals(fileEntity.getId());
return FileEntityResponse.builder()
.id(fileEntity.getId())
.userId(fileEntity.getUserId())
@@ -417,6 +422,30 @@ public class FileEntityService {
.protectedFilePath(fileEntity.getProtectedFilePath())
.thumbnailFileUrl(baseUrl + "/api/files/protected/" + fileEntity.getId() + "/thumbnail")
.permissions(fileEntity.getPermissions())
.appealInfos(appeals)
.build();
}
private List<Map<String, Object>> getFileAppeals(String fileId) {
List<FileAppeal> appeals = fileAppealRepository.findByFileId(fileId);
if (appeals == null || appeals.isEmpty()) {
return Collections.emptyList();
}
return appeals.stream()
.map(appeal -> {
Map<String, Object> appealMap = new HashMap<>();
appealMap.put("id", appeal.getId());
appealMap.put("userId", appeal.getUserId());
appealMap.put("appealReason", appeal.getAppealReason());
appealMap.put("additionalInfo", appeal.getAdditionalInfo());
appealMap.put("status", appeal.getStatus() != null ? appeal.getStatus().name() : null);
appealMap.put("adminComment", appeal.getAdminComment());
appealMap.put("moderatorId", appeal.getModeratorId());
appealMap.put("createdAt", appeal.getCreatedAt());
appealMap.put("resolvedAt", appeal.getResolvedAt());
return appealMap;
})
.collect(Collectors.toList());
}
}
@@ -30,12 +30,16 @@ import ru.soune.nocopy.service.cost.CostService;
import ru.soune.nocopy.service.file.FileEntityService;
import ru.soune.nocopy.service.file.FileUploadService;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;
import ru.soune.nocopy.service.file.moderation.ModerationFileService;
import ru.soune.nocopy.service.notification.NotificationService;
import ru.soune.nocopy.service.register.AuthService;
import ru.soune.nocopy.service.tariff.TariffInfoService;
import ru.soune.nocopy.util.FileUtil;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.PosixFilePermission;
@@ -93,6 +97,10 @@ public class FileUploadServiceImpl implements FileUploadService {
private final NotificationService notificationService;
private final AuthService authService;
private final ModerationFileService moderationFileService;
private final CloudStorageService cloudStorageService;
@PostConstruct
@@ -207,12 +207,7 @@ public class ModerationService {
.currentStatus(file.getStatus())
.uploadDate(file.getCreatedAt())
.hasActiveAppeal(activeAppeal != null)
.activeAppeal(activeAppeal != null ?
AppealInfo.builder()
.appealId(activeAppeal.getId())
.status(activeAppeal.getStatus().name())
.createdAt(activeAppeal.getCreatedAt())
.build() : null)
.activeAppeal(activeAppeal)
.build();
}
@@ -229,7 +224,8 @@ public class ModerationService {
}
@Transactional(readOnly = true)
public Page<FileEntity> getFilesForModeration(int page, int size, String sortDirection, String sortBy) {
public Page<FileEntity> getFilesForModeration(int page, int size, String sortDirection, String sortBy,
List<String> statuses, Boolean isAppeal) {
if (sortDirection == null || sortDirection.isEmpty()) {
sortDirection = "desc";
}
@@ -240,7 +236,8 @@ public class ModerationService {
Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.fromString(sortDirection), sortBy));
return fileEntityRepository.findByStatusIn(Arrays.asList(FileStatus.MODERATION, FileStatus.BLOCKED), pageable);
return isAppeal != null ? fileEntityRepository.findByStatusInAndSortedWithAppeal(statuses, pageable):
fileEntityRepository.findByStatusInAndSorted(statuses, pageable);
}
@@ -268,7 +265,7 @@ public class ModerationService {
.map(this::convertToResponse);
}
private AppealResponse convertToResponse(FileAppeal appeal) {
public AppealResponse convertToResponse(FileAppeal appeal) {
return AppealResponse.builder()
.appealId(appeal.getId())
.fileId(appeal.getFileId())
@@ -105,7 +105,6 @@ public class EmailService {
}
@Transactional
@Deprecated
public EmailVerificationToken createEmailVerificationToken(AuthToken authToken) {
EmailVerificationToken existingToken = emailVerificationTokenRepository
.findByUserId(authToken.getUser().getId());
@@ -122,23 +121,6 @@ public class EmailService {
return emailVerificationTokenRepository.save(emailToken);
}
@Transactional
public EmailVerificationToken createEmailVerificationToken(User user) {
EmailVerificationToken existingToken = emailVerificationTokenRepository
.findByUserId(user.getId());
if (existingToken != null) {
emailVerificationTokenRepository.deleteById(existingToken.getId());
}
EmailVerificationToken emailToken = new EmailVerificationToken();
emailToken.setUser(user);
emailToken.setToken(generateVerificationCode());
emailToken.setCreatedAt(LocalDateTime.now());
return emailVerificationTokenRepository.save(emailToken);
}
private String generateVerificationCode() {
SecureRandom random = new SecureRandom();
int code = 100000 + random.nextInt(900000);
@@ -0,0 +1,277 @@
package ru.soune.nocopy.service.register;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.*;
import ru.soune.nocopy.dto.register.AccountType;
import ru.soune.nocopy.dto.register.LoginAnswer;
import ru.soune.nocopy.dto.register.LoginRequest;
import ru.soune.nocopy.dto.register.RegRequest;
import ru.soune.nocopy.entity.company.Company;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.entity.user.AuthToken;
import ru.soune.nocopy.entity.user.Permission;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.entity.user.UserNotActive;
import ru.soune.nocopy.exception.CompanyAlreadyExist;
import ru.soune.nocopy.exception.NotFoundAuthToken;
import ru.soune.nocopy.exception.NotValidFieldException;
import ru.soune.nocopy.repository.*;
import ru.soune.nocopy.service.file.CheckCounterService;
import ru.soune.nocopy.service.tariff.TariffInfoService;
import java.security.SecureRandom;
import java.time.LocalDateTime;
import java.util.*;
@Service
@RequiredArgsConstructor
public class AuthService {
private final UserRepository userRepository;
private final AuthTokenRepository authTokenRepository;
private final PasswordEncoder passwordEncoder;
private final CompanyRepository companyRepository;
private final CheckCounterService checkCounterService;
private final TariffInfoRepository tariffInfoRepository;
private final TariffInfoService tariffInfoService;
private final UserNotActiveRepository userNotActiveRepository;
private final SecureRandom secureRandom = new SecureRandom();
@Transactional
public AuthToken register(RegRequest registerRequest, boolean verified) {
User user = new User();
user.setFullName(registerRequest.getFullName());
user.setEmail(registerRequest.getEmail());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
user.setActive(!verified);
user.setEmailVerified(!verified);
AccountType accountType = AccountType.valueOf(registerRequest.getAccountType().toUpperCase());
if (accountType == AccountType.B2B && registerRequest.getCompanyName() != null) {
try {
createCompanyAccount(registerRequest, user);
} catch (CompanyAlreadyExist exist) {
throw new CompanyAlreadyExist("Company already exist");
}
} else if (accountType == AccountType.B2C && registerRequest.getCompanyName() == null) {
createIndividualAccount(user);
} else {
createIndividualCompanyAccount(registerRequest, user);
}
if (registerRequest.getPhone() != null) {
user.setPhone(registerRequest.getPhone());
}
User savedUser = userRepository.save(user);
AuthToken authToken = genereateAuthToken(savedUser);
checkCounterService.initProtectCheckLimit(user, 0);
return authTokenRepository.save(authToken);
}
@Transactional
public Long useUserAuthToken(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"));
authToken.setLastUsedAt(LocalDateTime.now());
authToken.setExpiresAt(LocalDateTime.now().plusHours(1));
authTokenRepository.save(authToken);
return authToken.getUser().getId();
}
@Transactional
public User getUser(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"));
authToken.setLastUsedAt(LocalDateTime.now());
authToken.setExpiresAt(LocalDateTime.now().plusHours(1));
authTokenRepository.save(authToken);
return authToken.getUser();
}
public AuthToken login(LoginRequest request) {
User user = userRepository.findByEmail(request.getEmail());
if (!user.isActive()) {
throw new NotValidFieldException("User not active", new BaseResponse(20003,
MessageCode.USER_NOT_ACTIVE.getCode(),
MessageCode.USER_NOT_ACTIVE.getDescription(), Map.of("userId", user.getId())));
}
if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
LoginAnswer loginAnswer = new LoginAnswer();
loginAnswer.setFieldErrors(Arrays.asList(Map.of("password", request.getPassword())));
loginAnswer.setVerified(user.isEmailVerified());
loginAnswer.setActive(user.isActive());
int attempts = user.getFailedLoginAttempts() + 1;
user.setFailedLoginAttempts(attempts);
if (attempts >= 5) {
user.setActive(false);
blockUser(user);
}
userRepository.save(user);
throw new NotValidFieldException("Invalid password", new BaseResponse(20003,
MessageCode.AUTH_PASSWORD_NOT_MATCHES.getCode(),
MessageCode.AUTH_PASSWORD_NOT_MATCHES.getDescription(), loginAnswer));
}
user.setLastLoginAt(LocalDateTime.now());
user.setFailedLoginAttempts(0);
user.setActive(true);
User savedUser = userRepository.save(user);
AuthToken authToken = new AuthToken();
authToken.setToken(generateAuthToken());
authToken.setUser(savedUser);
return authTokenRepository.save(authToken);
}
@Transactional
public void logout(String token) {
authTokenRepository.findByToken(token)
.ifPresent(authTokenRepository::delete);
}
@Transactional
public AuthToken generateAuthToken(User user) {
return authTokenRepository.save(genereateAuthToken(user));
}
public AuthToken getAuthToken(String token) {
return authTokenRepository.findByToken(token).orElse(null);
}
private AuthToken genereateAuthToken(User user) {
AuthToken authToken = new AuthToken();
authToken.setToken(generateAuthToken());
authToken.setUser(user);
return authToken;
}
private String generateAuthToken() {
byte[] bytes = new byte[32];
secureRandom.nextBytes(bytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes);
}
private void createCompanyAccount(RegRequest request, User user) {
Optional<Company> byInn = companyRepository.findByInn(request.getInn());
if (byInn.isPresent()) {
throw new CompanyAlreadyExist("Company was already created");
}
Company company = new Company();
company.setCompanyName(request.getCompanyName());
company.setInn(request.getInn());
TariffInfo companyTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
company.setTariffInfo(companyTariff);
companyRepository.save(company);
tariffInfoService.addTariffInfo(companyTariff);
user.setCompany(company);
user.grantPermission(Permission.COMPANY_ADMIN_PERMISSIONS);
}
private void createIndividualAccount(User user) {
TariffInfo personalTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
tariffInfoService.addTariffInfo(personalTariff);
user.setPersonalTariffInfo(personalTariff);
user.grantPermission(Permission.DEFAULT_USER_PERMISSIONS);
}
private void createIndividualCompanyAccount(RegRequest request, User user) {
String authToken = request.getAuthToken();
Long userIdByToken = authTokenRepository.findUserIdByToken(authToken);
User companyUser = userRepository.findById(userIdByToken)
.orElseThrow(() -> new EntityNotFoundException("Not found token: " + authToken));
Company company = companyUser.getCompany();
if (company == null) {
throw new IllegalStateException("Not have company");
}
TariffInfo tariffInfo = company.getTariffInfo();
if (tariffInfo == null) {
throw new IllegalStateException("Company not have tariff");
}
// Tariff tariff = tariffInfo.getTariff();
// Long maxUsers = tariff.getMaxUsers();
// long currentCountUsers = userRepository.countByCompanyId(company.getId());
//
// if (currentCountUsers >= maxUsers) {
// throw new NotValidFieldException("Max user is over.", new BaseResponse(20002,
// MessageCode.USER_LIMIT_IS_OVER.getCode(),
// MessageCode.USER_LIMIT_IS_OVER.getDescription(), Map.of(
// "limit", maxUsers, "countUser", currentCountUsers)));
// }
user.setCompany(company);
user.grantPermission(Permission.DEFAULT_USER_PERMISSIONS);
}
public void blockUser(User user) {
Optional<UserNotActive> existing = userNotActiveRepository.findByUserId(user.getId());
if (existing.isEmpty()) {
LocalDateTime now = LocalDateTime.now();
UserNotActive notActive = UserNotActive.builder()
.user(user)
.createdAt(now)
.blockedUntil(now.plusMinutes(15))
.build();
userNotActiveRepository.save(notActive);
}
}
}
@@ -1,30 +1,21 @@
package ru.soune.nocopy.service.user;
import jakarta.persistence.EntityNotFoundException;
import lombok.AllArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.dto.register.AccountType;
import ru.soune.nocopy.dto.register.ChangePasswordRequest;
import ru.soune.nocopy.dto.register.RegRequest;
import ru.soune.nocopy.dto.tarriff.TariffInfoDTO;
import ru.soune.nocopy.dto.user.UserDTO;
import ru.soune.nocopy.dto.user.UserRequest;
import ru.soune.nocopy.entity.company.Company;
import ru.soune.nocopy.entity.tarif.Tariff;
import ru.soune.nocopy.entity.tarif.TariffInfo;
import ru.soune.nocopy.entity.tarif.TariffType;
import ru.soune.nocopy.entity.user.Permission;
import ru.soune.nocopy.entity.user.User;
import ru.soune.nocopy.exception.CompanyAlreadyExist;
import ru.soune.nocopy.exception.InvalidUserEmail;
import ru.soune.nocopy.exception.NotValidationPasswordException;
import ru.soune.nocopy.exception.UserNotFoundException;
import ru.soune.nocopy.repository.CompanyRepository;
import ru.soune.nocopy.repository.UserRepository;
import ru.soune.nocopy.service.file.FileStatsService;
import ru.soune.nocopy.service.tariff.TariffInfoService;
import java.util.List;
import java.util.Optional;
@@ -39,10 +30,6 @@ public class UserService {
private final FileStatsService fileStatsService;
private final CompanyRepository companyRepository;
private final TariffInfoService tariffInfoService;
@Transactional
public User changePassword(User user, ChangePasswordRequest request) {
if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) {
@@ -95,93 +82,6 @@ public class UserService {
return userRepository.save(user);
}
@Transactional
public User createUser(RegRequest registerRequest, boolean verified, Long createrId) {
User user = new User();
user.setFullName(registerRequest.getFullName());
user.setEmail(registerRequest.getEmail());
user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
user.setActive(!verified);
user.setEmailVerified(!verified);
AccountType accountType = AccountType.valueOf(registerRequest.getAccountType().toUpperCase());
if (accountType == AccountType.B2B && registerRequest.getCompanyName() != null) {
try {
createCompanyAccount(registerRequest, user);
} catch (CompanyAlreadyExist exist) {
throw new CompanyAlreadyExist("Company already exist");
}
} else if (accountType == AccountType.B2C && registerRequest.getCompanyName() == null) {
createIndividualAccount(user);
} else {
createIndividualCompanyAccount(user, createrId);
}
if (registerRequest.getPhone() != null) {
user.setPhone(registerRequest.getPhone());
}
return userRepository.save(user);
}
public Optional<User> getUserById(Long userId) {
return userRepository.findById(userId);
}
public boolean existsByEmailOrPhone(String email, String phone){
return userRepository.existsByEmail(email) || userRepository.existsByPhone(phone);
}
private void createCompanyAccount(RegRequest request, User user) {
Optional<Company> byInn = companyRepository.findByInn(request.getInn());
if (byInn.isPresent()) {
throw new CompanyAlreadyExist("Company was already created");
}
Company company = new Company();
company.setCompanyName(request.getCompanyName());
company.setInn(request.getInn());
TariffInfo companyTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
company.setTariffInfo(companyTariff);
companyRepository.save(company);
tariffInfoService.addTariffInfo(companyTariff);
user.setCompany(company);
user.grantPermission(Permission.COMPANY_ADMIN_PERMISSIONS);
}
private void createIndividualAccount(User user) {
TariffInfo personalTariff = tariffInfoService.createTariffInfo(TariffType.DEMO);
tariffInfoService.addTariffInfo(personalTariff);
user.setPersonalTariffInfo(personalTariff);
user.grantPermission(Permission.DEFAULT_USER_PERMISSIONS);
}
private void createIndividualCompanyAccount(User user, Long companyUserId) {
User companyUser = getUserById(companyUserId).orElseThrow(() ->
new EntityNotFoundException("Not found user id: " + companyUserId));
Company company = companyUser.getCompany();
if (company == null) {
throw new IllegalStateException("Not have company");
}
TariffInfo tariffInfo = company.getTariffInfo();
if (tariffInfo == null) {
throw new IllegalStateException("Company not have tariff");
}
user.setCompany(company);
user.grantPermission(Permission.DEFAULT_USER_PERMISSIONS);
}
private void updateUserFromRequest(User user, UserRequest request) {
if (request.getFullName() != null) {
user.setFullName(request.getFullName());
@@ -1,66 +0,0 @@
package ru.soune.nocopy.util;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import ru.soune.nocopy.dto.BaseResponse;
import ru.soune.nocopy.dto.MessageCode;
import java.io.IOException;
import java.util.List;
@Component
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtUtil jwtUtil;
private final ObjectMapper objectMapper;
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
filterChain.doFilter(request, response);
return;
}
String token = authHeader.substring(7);
if (!jwtUtil.validateToken(token)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json");
BaseResponse errorResponse = BaseResponse.builder()
.messageCode(MessageCode.INVALID_CREDENTIALS.getCode())
.messageDesc("Invalid or expired token")
.build();
response.getWriter().write(objectMapper.writeValueAsString(errorResponse));
return;
}
Long userId = jwtUtil.extractUserId(token);
String email = jwtUtil.extractEmail(token);
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(email, null, List.of(new SimpleGrantedAuthority("ROLE_USER")));
SecurityContextHolder.getContext().setAuthentication(authentication);
request.setAttribute("userId", userId);
request.setAttribute("email", email);
filterChain.doFilter(request, response);
}
}
@@ -1,65 +0,0 @@
package ru.soune.nocopy.util;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
@Component
public class JwtUtil {
@Value("${jwt.secret:Z29nb3Bvd2VycmFuZ2VydHVtYmF5YW1iZjMyNDIyMjh3aW5lcndpbmVy}")
private String secret;
@Value("${jwt.expiration:3600000}")
private Long expiration;
private SecretKey getSigningKey() {
return Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
}
public String generateToken(Long userId, String email) {
return Jwts.builder()
.setSubject(email)
.claim("userId", userId)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.signWith(getSigningKey(), SignatureAlgorithm.HS256)
.compact();
}
public Claims extractClaims(String token) {
return Jwts.parser()
.setSigningKey(getSigningKey())
.build()
.parseClaimsJws(token)
.getBody();
}
public String extractEmail(String token) {
return extractClaims(token).getSubject();
}
public Long extractUserId(String token) {
return extractClaims(token).get("userId", Long.class);
}
public boolean isTokenExpired(String token) {
return extractClaims(token).getExpiration().before(new Date());
}
public boolean validateToken(String token) {
try {
return !isTokenExpired(token);
} catch (Exception e) {
return false;
}
}
}
-4
View File
@@ -129,10 +129,6 @@ search:
host: "193.46.217.94"
port: 3128
jwt:
secret: SF9fsWH0ahlmTk9pKGXVdPHKxkdjUZnquCs9j7gYNZR
expiration: 3600000
yookassa:
secret-key: test_0Yns_0NHV5GJf6ypJ5HC4NSfnLO8SJkw-1PwrVWsDl4
shop-id: 1276731