Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
c20b33a305
|
|||
| a1dc9a840e | |||
| 508405077d | |||
| 36acd75eb3 | |||
|
5225174d51
|
|||
|
471d03d0b6
|
@@ -31,6 +31,3 @@ build/
|
|||||||
|
|
||||||
### VS Code ###
|
### VS Code ###
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
### apach-maven binary ###
|
|
||||||
apache-maven-3.9.6
|
|
||||||
|
|||||||
-34
@@ -1,34 +0,0 @@
|
|||||||
## BACKEND ##
|
|
||||||
|
|
||||||
# Base image
|
|
||||||
FROM debian:12-slim
|
|
||||||
|
|
||||||
# Metadata
|
|
||||||
LABEL maintainer="kshitijka"
|
|
||||||
LABEL version=1.0
|
|
||||||
LABEL description="Skycrate is a web based file management system that uses Hadoop as filesystem."
|
|
||||||
|
|
||||||
# Update & upgrade & install & rm
|
|
||||||
RUN apt-get update && apt-get upgrade -y && \
|
|
||||||
apt-get install -y openjdk-17-jdk && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Create non-root user
|
|
||||||
RUN useradd -s /bin/bash skycrateBack
|
|
||||||
|
|
||||||
# Create work dir
|
|
||||||
RUN mkdir /app
|
|
||||||
RUN chown -R skycrateBack:skycrateBack /app
|
|
||||||
COPY ./target/ /app
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# Create temp download directory
|
|
||||||
RUN mkdir -p /Skycrate/downloaded/
|
|
||||||
RUN chown -R skycrateBack:skycrateBack /Skycrate /Skycrate/downloaded/
|
|
||||||
|
|
||||||
# Switch user
|
|
||||||
USER skycrateBack
|
|
||||||
|
|
||||||
EXPOSE 8081
|
|
||||||
|
|
||||||
CMD ["java", "-jar", "/app/skycrateBackend-0.0.1-SNAPSHOT.jar"]
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -144,6 +144,16 @@
|
|||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
<version>2.11.0</version>
|
<version>2.11.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- NEWLY ADDED DEPENDENCY FOR DOWNLOAD ENDPOINT-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.11.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import java.security.PrivilegedExceptionAction;
|
|||||||
public class HDFSConfig {
|
public class HDFSConfig {
|
||||||
public static FileSystem getHDFS() throws Exception {
|
public static FileSystem getHDFS() throws Exception {
|
||||||
Configuration conf = new Configuration();
|
Configuration conf = new Configuration();
|
||||||
conf.set("fs.defaultFS", "hdfs://namenode:9000");
|
conf.set("fs.defaultFS", "hdfs://192.168.29.56:9000");
|
||||||
return FileSystem.get(new URI("hdfs://namenode:9000"), conf);
|
return FileSystem.get(new URI("hdfs://192.168.29.56:9000"), conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
protected void doFilterInternal(
|
protected void doFilterInternal(
|
||||||
@NonNull HttpServletRequest request,
|
@NonNull HttpServletRequest request,
|
||||||
@NonNull HttpServletResponse response,
|
@NonNull HttpServletResponse response,
|
||||||
@@ -59,6 +60,8 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||||||
);
|
);
|
||||||
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+87
-201
@@ -1,15 +1,11 @@
|
|||||||
package com.skycrate.backend.skycrateBackend.controller;
|
package com.skycrate.backend.skycrateBackend.controller;
|
||||||
|
|
||||||
import com.skycrate.backend.skycrateBackend.config.HDFSConfig;
|
|
||||||
import com.skycrate.backend.skycrateBackend.dto.ResponseDTO;
|
import com.skycrate.backend.skycrateBackend.dto.ResponseDTO;
|
||||||
import com.skycrate.backend.skycrateBackend.models.User;
|
|
||||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
|
||||||
import com.skycrate.backend.skycrateBackend.services.EncryptionUtil;
|
import com.skycrate.backend.skycrateBackend.services.EncryptionUtil;
|
||||||
import com.skycrate.backend.skycrateBackend.services.HDFSOperations;
|
import com.skycrate.backend.skycrateBackend.services.HDFSOperations;
|
||||||
import com.skycrate.backend.skycrateBackend.utils.KeyUtil;
|
import com.skycrate.backend.skycrateBackend.utils.KeyUtil;
|
||||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
@@ -21,7 +17,6 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -29,11 +24,6 @@ import java.util.List;
|
|||||||
import org.springframework.core.io.FileSystemResource; // For FileSystemResource
|
import org.springframework.core.io.FileSystemResource; // For FileSystemResource
|
||||||
import org.springframework.core.io.Resource; // For Resource
|
import org.springframework.core.io.Resource; // For Resource
|
||||||
import org.springframework.http.HttpHeaders; // For HttpHeaders
|
import org.springframework.http.HttpHeaders; // For HttpHeaders
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
|
||||||
import javax.crypto.KeyGenerator;
|
|
||||||
import javax.crypto.SecretKey;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.io.File; // For java.io.File
|
import java.io.File; // For java.io.File
|
||||||
|
|
||||||
import static com.skycrate.backend.skycrateBackend.utils.KeyUtil.getPrivateKeyForUser;
|
import static com.skycrate.backend.skycrateBackend.utils.KeyUtil.getPrivateKeyForUser;
|
||||||
@@ -45,10 +35,6 @@ public class HDFScontroller {
|
|||||||
|
|
||||||
private final HDFSOperations hdfsOperations;
|
private final HDFSOperations hdfsOperations;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserRepository userRepository;
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public HDFScontroller(HDFSOperations hdfsOperations) {
|
public HDFScontroller(HDFSOperations hdfsOperations) {
|
||||||
this.hdfsOperations = hdfsOperations;
|
this.hdfsOperations = hdfsOperations;
|
||||||
@@ -65,186 +51,107 @@ public class HDFScontroller {
|
|||||||
return new ResponseDTO("Failed to create folder: " + e.getMessage(), false);
|
return new ResponseDTO("Failed to create folder: " + e.getMessage(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
@PostMapping("/uploadFile")
|
// @PostMapping("/uploadFile")
|
||||||
public ResponseDTO uploadFile(
|
// public ResponseDTO uploadFile(
|
||||||
@RequestParam("file") MultipartFile file,
|
// @RequestParam("file") MultipartFile file,
|
||||||
@RequestParam String hdfsPath,
|
// @RequestParam String hdfsPath,
|
||||||
@RequestParam String uploadedFileName,
|
// @RequestParam String uploadedFileName,
|
||||||
@RequestParam String username) {
|
// @RequestParam String username) {
|
||||||
try {
|
// try {
|
||||||
// Retrieve the user from the database using the username
|
// // Save file locally first
|
||||||
User user = userRepository.findByUsername(username).orElseThrow(() -> new RuntimeException("User not found"));
|
// String localPath = saveFileLocally(file);
|
||||||
|
// System.out.println("File saved locally at: " + localPath);
|
||||||
// Get the public key from the user entity
|
//
|
||||||
byte[] publicKeyBytes = user.getPublicKey();
|
// // Upload file to HDFS
|
||||||
PublicKey publicKey = RSAKeyUtil.getPublicKeyFromBytes(publicKeyBytes);
|
// hdfsOperations.uploadFile(localPath, hdfsPath, uploadedFileName, username);
|
||||||
|
// return new ResponseDTO("File uploaded successfully", true);
|
||||||
// Encrypt the file content using the public key
|
// } catch (IOException e) {
|
||||||
byte[] encryptedData = encryptFile(file, publicKey);
|
// e.printStackTrace();
|
||||||
|
// return new ResponseDTO("Failed to upload file locally: " + e.getMessage(), false);
|
||||||
// Upload the encrypted file to HDFS
|
// } catch (Exception e) {
|
||||||
hdfsOperations.uploadFile(encryptedData, hdfsPath, uploadedFileName, username);
|
// e.printStackTrace();
|
||||||
|
// return new ResponseDTO("Failed to upload file to HDFS: " + e.getMessage(), false);
|
||||||
return new ResponseDTO("File uploaded successfully", true);
|
// }
|
||||||
} catch (IOException e) {
|
// }
|
||||||
e.printStackTrace();
|
@PostMapping("/uploadFile")
|
||||||
return new ResponseDTO("Failed to upload file locally: " + e.getMessage(), false);
|
public ResponseDTO uploadFile(
|
||||||
} catch (Exception e) {
|
@RequestParam("file") MultipartFile file,
|
||||||
e.printStackTrace();
|
@RequestParam String hdfsPath,
|
||||||
return new ResponseDTO("Failed to upload file to HDFS: " + e.getMessage(), false);
|
@RequestParam String uploadedFileName,
|
||||||
}
|
@RequestParam String username) {
|
||||||
|
try {
|
||||||
|
// Upload file directly to HDFS without saving locally
|
||||||
|
hdfsOperations.uploadFile(file, hdfsPath, uploadedFileName, username);
|
||||||
|
return new ResponseDTO("File uploaded successfully", true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new ResponseDTO("Failed to upload file to HDFS: " + e.getMessage(), false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method to encrypt the file content using RSA encryption
|
|
||||||
private byte[] encryptFile(MultipartFile file, PublicKey publicKey) throws Exception {
|
|
||||||
// Step 1: Generate a random AES key
|
|
||||||
SecretKey aesKey = generateAESKey();
|
|
||||||
|
|
||||||
// Step 2: Encrypt the file data using AES
|
//
|
||||||
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
// private String saveFileLocally(MultipartFile file) throws IOException {
|
||||||
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
|
// // Create a temporary directory if it doesn't exist
|
||||||
byte[] fileData = file.getBytes();
|
// Path tmpDir = Paths.get("tmp");
|
||||||
byte[] encryptedData = aesCipher.doFinal(fileData);
|
// if (!Files.exists(tmpDir)) {
|
||||||
|
// Files.createDirectories(tmpDir); // Create the directory if it doesn't exist
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Path path = tmpDir.resolve(file.getOriginalFilename());
|
||||||
|
//
|
||||||
|
// // Copy the file to the local directory
|
||||||
|
// Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
|
||||||
|
//
|
||||||
|
// return path.toString(); // Return the local path for further processing
|
||||||
|
// }
|
||||||
|
|
||||||
// Step 3: Encrypt the AES key with RSA
|
|
||||||
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
|
||||||
rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());
|
|
||||||
|
|
||||||
// Step 4: Combine the encrypted AES key and the encrypted data
|
// @PostMapping("/downloadFile")
|
||||||
byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length];
|
// public ResponseEntity<?> downloadFile(
|
||||||
combined[0] = (byte) (encryptedAesKey.length >> 24);
|
// @RequestParam String hdfsPath,
|
||||||
combined[1] = (byte) (encryptedAesKey.length >> 16);
|
// @RequestParam String username) {
|
||||||
combined[2] = (byte) (encryptedAesKey.length >> 8);
|
// try {
|
||||||
combined[3] = (byte) encryptedAesKey.length;
|
// // Define a temporary local path to download the file
|
||||||
|
// String localPath = "/app/tmp/downloaded/" + new File(hdfsPath).getName(); // Adjust the path as needed
|
||||||
System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length);
|
//
|
||||||
System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length);
|
// // Download the file from HDFS to the local path
|
||||||
|
// hdfsOperations.downloadFile(hdfsPath, localPath, username);
|
||||||
return combined;
|
//
|
||||||
}
|
// // Create a File object for the downloaded file
|
||||||
|
// File file = new File(localPath);
|
||||||
// Generate a random AES key
|
// if (!file.exists()) {
|
||||||
private SecretKey generateAESKey() throws NoSuchAlgorithmException {
|
// return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||||
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
|
// .body(new ResponseDTO("File not found", false));
|
||||||
keyGen.init(256); // Use 256 bits for AES
|
// }
|
||||||
return keyGen.generateKey();
|
//
|
||||||
}
|
// // Create a Resource from the file
|
||||||
|
// Resource resource = new FileSystemResource(file);
|
||||||
private String saveFileLocally(MultipartFile file) throws IOException {
|
// return ResponseEntity.ok()
|
||||||
// Create a temporary directory if it doesn't exist
|
// .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
|
||||||
Path tmpDir = Paths.get("tmp");
|
// .body(resource);
|
||||||
if (!Files.exists(tmpDir)) {
|
// } catch (Exception e) {
|
||||||
Files.createDirectories(tmpDir); // Create the directory if it doesn't exist
|
// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
}
|
// .body(new ResponseDTO("Failed to download file: " + e.getMessage(), false));
|
||||||
|
// }
|
||||||
Path path = tmpDir.resolve(file.getOriginalFilename());
|
// }
|
||||||
|
|
||||||
// Copy the file to the local directory
|
|
||||||
Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
|
|
||||||
|
|
||||||
return path.toString(); // Return the local path for further processing
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/downloadFile")
|
@PostMapping("/downloadFile")
|
||||||
public ResponseEntity<Resource> downloadFile(
|
public ResponseEntity<?> downloadFile(
|
||||||
@RequestParam String hdfsEncPath,
|
@RequestParam String hdfsPath,
|
||||||
@RequestParam String username) {
|
@RequestParam String username) {
|
||||||
try {
|
try {
|
||||||
// Extract the file name and extension
|
String fileName = new File(hdfsPath).getName();
|
||||||
String encFileName = new File(hdfsEncPath).getName();
|
InputStreamResource resource = hdfsOperations.downloadFile(hdfsPath, username);
|
||||||
String originalFileName = encFileName.replace(".enc", "");
|
|
||||||
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
|
|
||||||
|
|
||||||
// Define local decrypted file path
|
|
||||||
String localDecryptedPath = "/SkyCrate/downloaded/" + originalFileName;
|
|
||||||
|
|
||||||
// Define HDFS paths for encrypted file
|
|
||||||
String encFilePath = "/SkyCrate/downloaded/" + encFileName;
|
|
||||||
|
|
||||||
FileSystem fs = HDFSConfig.getHDFS();
|
|
||||||
|
|
||||||
// Download encrypted file from HDFS
|
|
||||||
fs.copyToLocalFile(new org.apache.hadoop.fs.Path(hdfsEncPath), new org.apache.hadoop.fs.Path(encFilePath));
|
|
||||||
|
|
||||||
// Retrieve the RSA private key for the user
|
|
||||||
User user = userRepository.findByUsername(username)
|
|
||||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
|
||||||
PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey());
|
|
||||||
|
|
||||||
// Read the encrypted file content
|
|
||||||
byte[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath));
|
|
||||||
|
|
||||||
// Step 1: Extract the AES key length from the combined data
|
|
||||||
int aesKeyLength = ((encryptedFileContent[0] & 0xFF) << 24) |
|
|
||||||
((encryptedFileContent[1] & 0xFF) << 16) |
|
|
||||||
((encryptedFileContent[2] & 0xFF) << 8) |
|
|
||||||
(encryptedFileContent[3] & 0xFF);
|
|
||||||
|
|
||||||
// Step 2: Extract the encrypted AES key and encrypted data
|
|
||||||
byte[] encryptedAesKey = new byte[aesKeyLength];
|
|
||||||
byte[] encryptedData = new byte[encryptedFileContent.length - 4 - aesKeyLength];
|
|
||||||
|
|
||||||
System.arraycopy(encryptedFileContent, 4, encryptedAesKey, 0, aesKeyLength);
|
|
||||||
System.arraycopy(encryptedFileContent, 4 + aesKeyLength, encryptedData, 0, encryptedData.length);
|
|
||||||
|
|
||||||
// Step 3: Decrypt the AES key using RSA
|
|
||||||
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
|
||||||
rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
|
|
||||||
|
|
||||||
// Create the AES key
|
|
||||||
SecretKey aesKey = new SecretKeySpec(aesKeyBytes, "AES");
|
|
||||||
|
|
||||||
// Step 4: Decrypt the data using AES
|
|
||||||
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
|
||||||
aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
|
|
||||||
|
|
||||||
// Decrypt the file content using the provided decrypt method
|
|
||||||
// byte[] decryptedFileContent = RSAKeyUtil.decrypt(encryptedFileContent, privateKey);
|
|
||||||
byte[] decryptedFileContent = aesCipher.doFinal(encryptedData);
|
|
||||||
|
|
||||||
// Write the decrypted content to the original file
|
|
||||||
Files.write(Paths.get(localDecryptedPath + "." + fileExtension), decryptedFileContent);
|
|
||||||
|
|
||||||
|
|
||||||
// Log the file creation
|
|
||||||
if (Files.exists(Paths.get(localDecryptedPath + "." + fileExtension))) {
|
|
||||||
System.out.println("File created successfully at: " + localDecryptedPath + "." + fileExtension);
|
|
||||||
} else {
|
|
||||||
System.out.println("Failed to create file at: " + localDecryptedPath + "." + fileExtension);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the decrypted file resource
|
|
||||||
File decryptedFile = new File(localDecryptedPath + "." + fileExtension);
|
|
||||||
Resource resource = new FileSystemResource(decryptedFile);
|
|
||||||
|
|
||||||
// Return the file as a response
|
|
||||||
return ResponseEntity.ok()
|
return ResponseEntity.ok()
|
||||||
.contentLength(decryptedFile.length())
|
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
|
||||||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + decryptedFile.getName() + "\"")
|
|
||||||
.body(resource);
|
.body(resource);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
.body(null);
|
.body(new ResponseDTO("Failed to download file: " + e.getMessage(), false));
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void initializeKeysForUser(String username) {
|
|
||||||
try {
|
|
||||||
// Check if the public key file exists
|
|
||||||
Path publicKeyPath = Paths.get("C:\\Users\\sonal\\OneDrive\\Desktop\\SkyCrate\\Skycrate\\keys", username + "_public.key");
|
|
||||||
if (!Files.exists(publicKeyPath)) {
|
|
||||||
// Generate and store keys if they do not exist
|
|
||||||
KeyUtil.generateAndStoreKeyPair(username);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,25 +186,4 @@ public class HDFScontroller {
|
|||||||
.body("Failed to list files: " + e.getMessage());
|
.body("Failed to list files: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@GetMapping("/getUsernameByEmail")
|
|
||||||
public ResponseEntity<?> getUsernameByEmail(@RequestParam String email) {
|
|
||||||
try {
|
|
||||||
// Fetch user from the database using the provided email
|
|
||||||
User user = userRepository.findByEmail(email)
|
|
||||||
.orElseThrow(() -> new RuntimeException("User not found with email: " + email));
|
|
||||||
|
|
||||||
// // Log the retrieved user object to verify the username
|
|
||||||
// System.out.println("Retrieved user: " + user.getFullname());
|
|
||||||
|
|
||||||
// Return the username as the response
|
|
||||||
return ResponseEntity.ok(user.getFullname()); // Return the username
|
|
||||||
} catch (Exception e) {
|
|
||||||
// Handle error if user is not found or other exceptions occur
|
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
|
||||||
.body("Failed to fetch username: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.skycrate.backend.skycrateBackend.models;
|
package com.skycrate.backend.skycrateBackend.models;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -6,6 +6,7 @@ import java.util.Date;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hibernate.annotations.CreationTimestamp;
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
import org.hibernate.annotations.UpdateTimestamp;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
@@ -14,7 +15,7 @@ import jakarta.persistence.*;
|
|||||||
@Table(name = "users")
|
@Table(name = "users")
|
||||||
@Entity
|
@Entity
|
||||||
public class User implements UserDetails {
|
public class User implements UserDetails {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
@@ -23,38 +24,49 @@ public class User implements UserDetails {
|
|||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
//Optional feature might add later
|
||||||
|
|
||||||
|
@Column(name = "verification_code")
|
||||||
|
private String verificationCode;
|
||||||
|
|
||||||
|
@Column(name ="verification_expiry")
|
||||||
|
private LocalDateTime verificationExpiry;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
@Column(unique = true, nullable = false)
|
@Column(unique = true, nullable = false)
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@Column(nullable = false)
|
@Column(nullable = false)
|
||||||
private String password;
|
private String password;
|
||||||
|
|
||||||
// ✅ Add RSA key fields
|
|
||||||
@Lob
|
|
||||||
@Column(name = "public_key", columnDefinition = "BLOB")
|
public User(){
|
||||||
private byte[] publicKey;
|
}
|
||||||
|
|
||||||
@Lob
|
public User(String firstname,String lastname,String email,String password){
|
||||||
@Column(name = "private_key", columnDefinition = "BLOB")
|
this.username=firstname+lastname;
|
||||||
private byte[] privateKey;
|
this.email=email;
|
||||||
|
this.password=password;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@CreationTimestamp
|
@CreationTimestamp
|
||||||
@Column(updatable = false, name = "created_at")
|
@Column(updatable = false, name = "created_at")
|
||||||
private Date createdAt;
|
private Date createdAt;
|
||||||
|
|
||||||
public User() {}
|
|
||||||
|
|
||||||
public User(String firstname, String lastname, String email, String password) {
|
@Override
|
||||||
this.username = firstname + lastname;
|
public Collection<? extends GrantedAuthority> getAuthorities(){
|
||||||
this.email = email;
|
return List.of();
|
||||||
this.password = password;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⬇️ Required by Spring Security
|
public String getPassword() {
|
||||||
@Override
|
return password;
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
|
||||||
return List.of();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -62,11 +74,6 @@ public class User implements UserDetails {
|
|||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPassword() {
|
|
||||||
return password;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAccountNonExpired() {
|
public boolean isAccountNonExpired() {
|
||||||
return true;
|
return true;
|
||||||
@@ -86,8 +93,6 @@ public class User implements UserDetails {
|
|||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ⬇️ Getters and Setters
|
|
||||||
public Integer getId() {
|
public Integer getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@@ -96,11 +101,13 @@ public class User implements UserDetails {
|
|||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFullname(String firstname, String lastname) {
|
|
||||||
this.username = firstname + lastname;
|
|
||||||
|
public void setFullname(String firstname,String lastname) {
|
||||||
|
this.username=firstname+lastname;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFullname() {
|
public String getFullname(String firstname,String lastname){
|
||||||
return this.username;
|
return this.username;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,21 +126,4 @@ public class User implements UserDetails {
|
|||||||
public void setCreatedAt(Date createdAt) {
|
public void setCreatedAt(Date createdAt) {
|
||||||
this.createdAt = createdAt;
|
this.createdAt = createdAt;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ✅ Getters and setters for RSA keys
|
|
||||||
public byte[] getPublicKey() {
|
|
||||||
return publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPublicKey(byte[] publicKey) {
|
|
||||||
this.publicKey = publicKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getPrivateKey() {
|
|
||||||
return privateKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrivateKey(byte[] privateKey) {
|
|
||||||
this.privateKey = privateKey;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import org.springframework.data.repository.CrudRepository;
|
|||||||
import com.skycrate.backend.skycrateBackend.models.User;
|
import com.skycrate.backend.skycrateBackend.models.User;
|
||||||
public interface UserRepository extends CrudRepository<User,Integer> {
|
public interface UserRepository extends CrudRepository<User,Integer> {
|
||||||
Optional<User> findByEmail(String email);
|
Optional<User> findByEmail(String email);
|
||||||
// Custom query method to find user by username
|
|
||||||
Optional<User> findByUsername(String username);
|
|
||||||
/*
|
/*
|
||||||
// might use later
|
// might use later
|
||||||
Optional<User> findByVerificationCode(String verificationCode);
|
Optional<User> findByVerificationCode(String verificationCode);
|
||||||
|
|||||||
+20
-32
@@ -9,49 +9,37 @@ import com.skycrate.backend.skycrateBackend.dto.LoginUserDto;
|
|||||||
import com.skycrate.backend.skycrateBackend.dto.RegisterUserDto;
|
import com.skycrate.backend.skycrateBackend.dto.RegisterUserDto;
|
||||||
import com.skycrate.backend.skycrateBackend.models.User;
|
import com.skycrate.backend.skycrateBackend.models.User;
|
||||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
||||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
|
||||||
|
|
||||||
import java.security.KeyPair;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AuthenticationService {
|
public class AuthenticationService {
|
||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
private final AuthenticationManager authenticationManager;
|
private final AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
public AuthenticationService(UserRepository userRepository, AuthenticationManager authenticationManager, PasswordEncoder passwordEncoder) {
|
public AuthenticationService( UserRepository userRepository, AuthenticationManager authenticationManager , PasswordEncoder passwordEncoder){
|
||||||
this.userRepository = userRepository;
|
this.userRepository=userRepository;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder=passwordEncoder;
|
||||||
this.authenticationManager = authenticationManager;
|
this.authenticationManager=authenticationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public User signUp(RegisterUserDto inputUser) {
|
public User signUp(RegisterUserDto inputuser){
|
||||||
User user = new User(
|
User user=new User(inputuser.getFirstname(),inputuser.getLastname(),inputuser.getEmail(),passwordEncoder.encode(inputuser.getPassword()));
|
||||||
inputUser.getFirstname(),
|
/*
|
||||||
inputUser.getLastname(),
|
User user = new User()
|
||||||
inputUser.getEmail(),
|
.setFullname(inputuser.getFirstname(),inputuser.getLastname())
|
||||||
passwordEncoder.encode(inputUser.getPassword())
|
.setEmail(inputuser.getEmail())
|
||||||
);
|
.setPassword(passwordEncoder.encode(inputuser.getPassword()));
|
||||||
|
*/
|
||||||
|
|
||||||
try {
|
return userRepository.save(user) ;
|
||||||
KeyPair keyPair = RSAKeyUtil.generateKeyPair();
|
|
||||||
user.setPublicKey(keyPair.getPublic().getEncoded());
|
|
||||||
user.setPrivateKey(keyPair.getPrivate().getEncoded());
|
|
||||||
} catch (NoSuchAlgorithmException e) {
|
|
||||||
throw new RuntimeException("Failed to generate RSA key pair", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return userRepository.save(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public User authenticate(LoginUserDto inputUser) {
|
public User authenticate(LoginUserDto inputuser){
|
||||||
authenticationManager.authenticate(
|
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(inputuser.getEmail()
|
||||||
new UsernamePasswordAuthenticationToken(inputUser.getEmail(), inputUser.getPassword())
|
, inputuser.getPassword()));
|
||||||
);
|
return userRepository.findByEmail(inputuser.getEmail()).orElseThrow();
|
||||||
|
|
||||||
return userRepository.findByEmail(inputUser.getEmail())
|
|
||||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package com.skycrate.backend.skycrateBackend.services;
|
package com.skycrate.backend.skycrateBackend.services;
|
||||||
|
|
||||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
|
||||||
|
|
||||||
import javax.crypto.*;
|
import javax.crypto.*;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class EncryptionUtil {
|
public class EncryptionUtil {
|
||||||
private static final String RSA_ALGORITHM = "RSA";
|
private static final String RSA_ALGORITHM = "RSA";
|
||||||
@@ -20,57 +19,36 @@ public class EncryptionUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt data using AES (AES Key is encrypted using RSA)
|
// Encrypt data using AES (AES Key is encrypted using RSA)
|
||||||
// public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
|
|
||||||
// // Step 1: Generate AES Key
|
|
||||||
// SecretKey aesKey = generateAESKey();
|
|
||||||
//
|
|
||||||
// // Encrypt data using AES
|
|
||||||
// Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
|
||||||
// aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
|
|
||||||
// byte[] encryptedData = aesCipher.doFinal(data);
|
|
||||||
//
|
|
||||||
// // Encrypt the AES key with RSA
|
|
||||||
// Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
|
||||||
// rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
// byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());
|
|
||||||
//
|
|
||||||
// // Step 4: Combine encrypted AES key and encrypted data into one array
|
|
||||||
// byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length];
|
|
||||||
//
|
|
||||||
// // First 4 bytes indicate the length of the AES encrypted key
|
|
||||||
// combined[0] = (byte) (encryptedAesKey.length >> 24);
|
|
||||||
// combined[1] = (byte) (encryptedAesKey.length >> 16);
|
|
||||||
// combined[2] = (byte) (encryptedAesKey.length >> 8);
|
|
||||||
// combined[3] = (byte) encryptedAesKey.length;
|
|
||||||
//
|
|
||||||
// // Copy AES Key and Encrypted Data into the combined array
|
|
||||||
// System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length);
|
|
||||||
// System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length);
|
|
||||||
//
|
|
||||||
// return combined;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
|
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
|
||||||
SecretKey aesKey = RSAKeyUtil.generateAESKey(256); // Ensure 256 bits
|
// Step 1: Generate AES Key
|
||||||
byte[] encryptedData = encryptDataWithAES(data, aesKey);
|
SecretKey aesKey = generateAESKey();
|
||||||
byte[] encryptedAesKey = RSAKeyUtil.encryptAESKey(aesKey, publicKey);
|
|
||||||
return combineEncryptedData(encryptedAesKey, encryptedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] encryptDataWithAES(byte[] data, SecretKey aesKey) throws Exception {
|
// Step 2: Encrypt data using AES
|
||||||
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
Cipher aesCipher = Cipher.getInstance(AES_ALGORITHM);
|
||||||
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
|
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
|
||||||
return aesCipher.doFinal(data);
|
byte[] encryptedData = aesCipher.doFinal(data);
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] combineEncryptedData(byte[] encryptedAesKey, byte[] encryptedData) {
|
// Step 3: Encrypt the AES key with RSA
|
||||||
|
Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||||
|
rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||||
|
byte[] encryptedAesKey = rsaCipher.doFinal(aesKey.getEncoded());
|
||||||
|
|
||||||
|
// Step 4: Combine encrypted AES key and encrypted data into one array
|
||||||
byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length];
|
byte[] combined = new byte[4 + encryptedAesKey.length + encryptedData.length];
|
||||||
|
|
||||||
|
// First 4 bytes indicate the length of the AES encrypted key
|
||||||
|
combined[0] = (byte) (encryptedAesKey.length >> 24);
|
||||||
|
combined[1] = (byte) (encryptedAesKey.length >> 16);
|
||||||
|
combined[2] = (byte) (encryptedAesKey.length >> 8);
|
||||||
|
combined[3] = (byte) encryptedAesKey.length;
|
||||||
|
|
||||||
|
// Copy AES Key and Encrypted Data into the combined array
|
||||||
System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length);
|
System.arraycopy(encryptedAesKey, 0, combined, 4, encryptedAesKey.length);
|
||||||
System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length);
|
System.arraycopy(encryptedData, 0, combined, 4 + encryptedAesKey.length, encryptedData.length);
|
||||||
|
|
||||||
return combined;
|
return combined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Decrypt data using RSA (AES Key is decrypted using RSA, then used for AES decryption)
|
// Decrypt data using RSA (AES Key is decrypted using RSA, then used for AES decryption)
|
||||||
public static byte[] decrypt(byte[] encryptedCombined, PrivateKey privateKey) throws Exception {
|
public static byte[] decrypt(byte[] encryptedCombined, PrivateKey privateKey) throws Exception {
|
||||||
// Step 1: Extract AES Key length from the combined data
|
// Step 1: Extract AES Key length from the combined data
|
||||||
@@ -87,16 +65,21 @@ public class EncryptionUtil {
|
|||||||
System.arraycopy(encryptedCombined, 4 + aesKeyLength, encryptedData, 0, encryptedData.length);
|
System.arraycopy(encryptedCombined, 4 + aesKeyLength, encryptedData, 0, encryptedData.length);
|
||||||
|
|
||||||
// Step 3: Decrypt the AES key using RSA
|
// Step 3: Decrypt the AES key using RSA
|
||||||
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
|
Cipher rsaCipher = Cipher.getInstance(RSA_ALGORITHM);
|
||||||
rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||||
byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
|
byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
|
||||||
|
SecretKey aesKey = new SecretKeySpec(aesKeyBytes, AES_ALGORITHM);
|
||||||
|
|
||||||
// Create AES key
|
// Step 4: Decrypt the data using AES
|
||||||
SecretKey aesKey = new SecretKeySpec(aesKeyBytes, "AES");
|
Cipher aesCipher = Cipher.getInstance(AES_ALGORITHM);
|
||||||
|
|
||||||
// Decrypt the data using AES
|
|
||||||
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
|
||||||
aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
|
aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
|
||||||
return aesCipher.doFinal(encryptedData);
|
return aesCipher.doFinal(encryptedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate a random AES key
|
||||||
|
private static SecretKey generateAESKey() throws NoSuchAlgorithmException {
|
||||||
|
KeyGenerator keyGen = KeyGenerator.getInstance(AES_ALGORITHM);
|
||||||
|
keyGen.init(AES_KEY_SIZE);
|
||||||
|
return keyGen.generateKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,12 @@
|
|||||||
package com.skycrate.backend.skycrateBackend.services;
|
package com.skycrate.backend.skycrateBackend.services;
|
||||||
|
|
||||||
import com.skycrate.backend.skycrateBackend.config.HDFSConfig;
|
import com.skycrate.backend.skycrateBackend.config.HDFSConfig;
|
||||||
import com.skycrate.backend.skycrateBackend.models.User;
|
import com.skycrate.backend.skycrateBackend.utils.KeyUtil;
|
||||||
import com.skycrate.backend.skycrateBackend.repository.UserRepository;
|
import org.apache.commons.io.IOUtils;
|
||||||
import com.skycrate.backend.skycrateBackend.utils.RSAKeyUtil;
|
import org.apache.hadoop.fs.*;
|
||||||
import org.apache.hadoop.fs.FSDataOutputStream;
|
import org.springframework.core.io.InputStreamResource;
|
||||||
import org.apache.hadoop.fs.FileStatus;
|
|
||||||
import org.apache.hadoop.fs.FileSystem;
|
|
||||||
import org.apache.hadoop.fs.Path;
|
|
||||||
import org.apache.hadoop.io.IOUtils;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.KeyGenerator;
|
import javax.crypto.KeyGenerator;
|
||||||
@@ -18,7 +14,6 @@ import javax.crypto.SecretKey;
|
|||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
@@ -32,129 +27,97 @@ import java.util.List;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class HDFSOperations {
|
public class HDFSOperations {
|
||||||
private final UserRepository userRepository;
|
|
||||||
|
|
||||||
@Autowired
|
// public void uploadFile(String localPath, String hdfsPath, String uploadedFileName, String username) {
|
||||||
public HDFSOperations(UserRepository userRepository) {
|
|
||||||
this.userRepository = userRepository;
|
|
||||||
}
|
|
||||||
|
|
||||||
// public void uploadFile(byte[] fileData, String hdfsPath, String uploadedFileName, String username) {
|
|
||||||
// try {
|
// try {
|
||||||
// FileSystem fs = HDFSConfig.getHDFS();
|
// FileSystem fs = HDFSConfig.getHDFS();
|
||||||
|
// byte[] data = Files.readAllBytes(Paths.get(localPath)); // Read file as bytes
|
||||||
//
|
//
|
||||||
// // Create an InputStream from the byte array
|
// // Encrypt file (consider adding encryption here as needed)
|
||||||
// ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData);
|
// byte[] encryptedData = data;
|
||||||
|
//
|
||||||
|
// String tempFilePath = localPath + ".enc";
|
||||||
|
// Files.write(Paths.get(tempFilePath), encryptedData);
|
||||||
//
|
//
|
||||||
// // Prepare the path for HDFS
|
|
||||||
// String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName;
|
// String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName;
|
||||||
|
// fs.copyFromLocalFile(new Path(tempFilePath), new Path(finalHdfsPath));
|
||||||
//
|
//
|
||||||
// // Upload the file directly to HDFS from the InputStream
|
// Files.delete(Paths.get(tempFilePath));
|
||||||
// Path hdfsFilePath = new Path(finalHdfsPath);
|
|
||||||
// FSDataOutputStream outputStream = fs.create(hdfsFilePath);
|
|
||||||
// IOUtils.copyBytes(inputStream, outputStream, 4096, true);
|
|
||||||
//
|
|
||||||
// } catch (IOException e) {
|
// } catch (IOException e) {
|
||||||
// // Handle I/O exception and log the error
|
// // Handle I/O exception and log the error
|
||||||
// throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e);
|
// throw new RuntimeException("Failed to upload file due to I/O issue: " + e.getMessage(), e);
|
||||||
// } catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
// // Catch any other exceptions
|
// // Catch any other exceptions
|
||||||
// throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e);
|
// throw new RuntimeException("Failed to upload file: " + e.getMessage(), e);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
|
||||||
// public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) {
|
public void uploadFile(MultipartFile file, String hdfsPath, String uploadedFileName, String username) {
|
||||||
|
try {
|
||||||
|
FileSystem fs = HDFSConfig.getHDFS();
|
||||||
|
|
||||||
|
// Encrypt file data if needed (currently direct pass-through)
|
||||||
|
byte[] fileBytes = file.getBytes(); // directly get bytes from MultipartFile
|
||||||
|
byte[] encryptedData = fileBytes;
|
||||||
|
|
||||||
|
// Define final HDFS file path
|
||||||
|
String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName;
|
||||||
|
|
||||||
|
// Write encrypted bytes directly to HDFS
|
||||||
|
Path hdfsDestPath = new Path(finalHdfsPath);
|
||||||
|
try (FSDataOutputStream outputStream = fs.create(hdfsDestPath, true)) {
|
||||||
|
outputStream.write(encryptedData);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to upload file due to I/O issue: " + e.getMessage(), e);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to upload file: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// public void downloadFile(String hdfsPath, String localPath, String username) {
|
||||||
// try {
|
// try {
|
||||||
// FileSystem fs = HDFSConfig.getHDFS();
|
// FileSystem fs = HDFSConfig.getHDFS();
|
||||||
|
// String tempFilePath = localPath + ".enc";
|
||||||
//
|
//
|
||||||
// // Extract file name and extension
|
// fs.copyToLocalFile(new Path(hdfsPath), new Path(tempFilePath));
|
||||||
// String encFileName = new File(hdfsEncPath).getName();
|
|
||||||
// String originalFileName = encFileName.replace(".enc", "");
|
|
||||||
// String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
|
|
||||||
//
|
//
|
||||||
// String fullDecryptedPath = localPathWithoutExt + "/" + originalFileName;
|
// byte[] encryptedData = Files.readAllBytes(Paths.get(tempFilePath));
|
||||||
// String encFilePath = fullDecryptedPath + ".enc";
|
// byte[] decryptedData = encryptedData; // Decrypt if needed
|
||||||
// String keyFilePath = fullDecryptedPath + ".key";
|
|
||||||
//
|
|
||||||
// // Download encrypted file and AES key from HDFS
|
|
||||||
// fs.copyToLocalFile(new Path(hdfsEncPath), new Path(encFilePath));
|
|
||||||
// fs.copyToLocalFile(new Path(hdfsEncPath.replace(".enc", ".key")), new Path(keyFilePath));
|
|
||||||
//
|
|
||||||
// // Read the encrypted AES key
|
|
||||||
// byte[] encryptedAesKey = Files.readAllBytes(Paths.get(keyFilePath));
|
|
||||||
// System.out.println("Length of encrypted AES key: " + encryptedAesKey.length);
|
|
||||||
//
|
|
||||||
// // Retrieve the RSA private key for the user
|
|
||||||
// User user = userRepository.findByUsername(username)
|
|
||||||
// .orElseThrow(() -> new RuntimeException("User not found"));
|
|
||||||
// PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey());
|
|
||||||
//
|
|
||||||
// Cipher rsaCipher = Cipher.getInstance("RSA");
|
|
||||||
// rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
// byte[] aesKeyBytes = rsaCipher.doFinal(encryptedAesKey);
|
|
||||||
//
|
|
||||||
// // Ensure valid AES key length
|
|
||||||
// if (aesKeyBytes.length != 16 && aesKeyBytes.length != 24 && aesKeyBytes.length != 32) {
|
|
||||||
// throw new RuntimeException("Invalid AES key length: " + aesKeyBytes.length + " bytes");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// SecretKey aesKey = new SecretKeySpec(aesKeyBytes, 0, aesKeyBytes.length, "AES");
|
|
||||||
//
|
|
||||||
// // Read the encrypted file content
|
|
||||||
// byte[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath));
|
|
||||||
//
|
|
||||||
// // Decrypt the file content using AES
|
|
||||||
// Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); // Specify padding
|
|
||||||
// aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
|
|
||||||
// byte[] decryptedFileContent = aesCipher.doFinal(encryptedFileContent);
|
|
||||||
//
|
|
||||||
// // Write the decrypted content to the original file
|
|
||||||
// Files.write(Paths.get(fullDecryptedPath + "." + fileExtension), decryptedFileContent);
|
|
||||||
//
|
|
||||||
// // Cleanup temporary files
|
|
||||||
// Files.deleteIfExists(Paths.get(encFilePath));
|
|
||||||
// Files.deleteIfExists(Paths.get(keyFilePath));
|
|
||||||
//
|
//
|
||||||
|
// Files.write(Paths.get(localPath), decryptedData);
|
||||||
|
// Files.delete(Paths.get(tempFilePath));
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// // Handle I/O exception and log the error
|
||||||
|
// throw new RuntimeException("Failed to download file due to I/O issue: " + e.getMessage(), e);
|
||||||
// } catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
// throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e);
|
// // Catch any other exceptions
|
||||||
|
// throw new RuntimeException("Failed to download file: " + e.getMessage(), e);
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public void uploadFile(byte[] fileData, String hdfsPath, String uploadedFileName, String username) {
|
public InputStreamResource downloadFile(String hdfsPath, String username) {
|
||||||
try {
|
try {
|
||||||
FileSystem fs = HDFSConfig.getHDFS();
|
FileSystem fs = HDFSConfig.getHDFS();
|
||||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(fileData);
|
|
||||||
String finalHdfsPath = hdfsPath.endsWith("/") ? hdfsPath + uploadedFileName : hdfsPath + "/" + uploadedFileName;
|
// Read encrypted file directly from HDFS
|
||||||
Path hdfsFilePath = new Path(finalHdfsPath);
|
FSDataInputStream hdfsInputStream = fs.open(new Path(hdfsPath));
|
||||||
try (FSDataOutputStream outputStream = fs.create(hdfsFilePath)) {
|
|
||||||
IOUtils.copyBytes(inputStream, outputStream, 4096, true);
|
// Optional: If decryption is needed, read bytes, decrypt, and wrap in ByteArrayInputStream
|
||||||
}
|
byte[] encryptedData = IOUtils.toByteArray(hdfsInputStream);
|
||||||
|
byte[] decryptedData = encryptedData; // Apply decryption if needed
|
||||||
|
|
||||||
|
return new InputStreamResource(new ByteArrayInputStream(decryptedData));
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Failed to upload file to HDFS: " + e.getMessage(), e);
|
throw new RuntimeException("Failed to stream file due to I/O issue: " + e.getMessage(), e);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException("Failed to stream file: " + e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void downloadFile(String hdfsEncPath, String localPathWithoutExt, String username) {
|
|
||||||
try {
|
|
||||||
FileSystem fs = HDFSConfig.getHDFS();
|
|
||||||
String encFilePath = localPathWithoutExt + ".enc";
|
|
||||||
fs.copyToLocalFile(new Path(hdfsEncPath), new Path(encFilePath));
|
|
||||||
|
|
||||||
User user = userRepository.findByUsername(username)
|
|
||||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
|
||||||
PrivateKey privateKey = RSAKeyUtil.getPrivateKeyFromBytes(user.getPrivateKey());
|
|
||||||
|
|
||||||
byte[] encryptedFileContent = Files.readAllBytes(Paths.get(encFilePath));
|
|
||||||
byte[] decryptedFileContent = RSAKeyUtil.decrypt(encryptedFileContent, privateKey);
|
|
||||||
|
|
||||||
Files.write(Paths.get(localPathWithoutExt), decryptedFileContent);
|
|
||||||
Files.deleteIfExists(Paths.get(encFilePath));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException("Failed to download or decrypt file: " + e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void createFolder(String hdfsPath) {
|
public void createFolder(String hdfsPath) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -3,37 +3,24 @@ package com.skycrate.backend.skycrateBackend.utils;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.security.*;
|
import java.security.KeyFactory;
|
||||||
|
import java.security.PrivateKey;
|
||||||
|
import java.security.PublicKey;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
|
|
||||||
public class KeyUtil {
|
public class KeyUtil {
|
||||||
|
|
||||||
public static void generateAndStoreKeyPair(String username) throws Exception {
|
|
||||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
|
||||||
keyPairGenerator.initialize(2048); // Key size
|
|
||||||
KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
|
||||||
|
|
||||||
// Store the public key
|
|
||||||
Path publicKeyPath = Paths.get("C:\\Users\\sonal\\OneDrive\\Desktop\\SkyCrate\\Skycrate\\keys", username + "_public.key");
|
|
||||||
Files.write(publicKeyPath, keyPair.getPublic().getEncoded());
|
|
||||||
|
|
||||||
// Store the private key
|
|
||||||
Path privateKeyPath = Paths.get("C:\\Users\\sonal\\OneDrive\\Desktop\\SkyCrate\\Skycrate\\keys", username + "_private.key");
|
|
||||||
Files.write(privateKeyPath, keyPair.getPrivate().getEncoded());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PublicKey getPublicKeyForUser(String username) throws Exception {
|
|
||||||
Path path = Paths.get("C:\\Users\\sonal\\OneDrive\\Desktop\\SkyCrate\\Skycrate\\keys", username + "_public.key");
|
|
||||||
byte[] bytes = Files.readAllBytes(path);
|
|
||||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
|
|
||||||
return KeyFactory.getInstance("RSA").generatePublic(keySpec);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static PrivateKey getPrivateKeyForUser(String username) throws Exception {
|
public static PrivateKey getPrivateKeyForUser(String username) throws Exception {
|
||||||
Path path = Paths.get("C:\\Users\\sonal\\OneDrive\\Desktop\\SkyCrate\\Skycrate\\keys", username + "_private.key");
|
Path path = Paths.get("keys", username + "_private.key");
|
||||||
byte[] bytes = Files.readAllBytes(path);
|
byte[] bytes = Files.readAllBytes(path);
|
||||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
|
||||||
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
return KeyFactory.getInstance("RSA").generatePrivate(keySpec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static PublicKey getPublicKeyForUser(String username) throws Exception {
|
||||||
|
Path path = Paths.get("keys", username + "_public.key");
|
||||||
|
byte[] bytes = Files.readAllBytes(path);
|
||||||
|
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
|
||||||
|
return KeyFactory.getInstance("RSA").generatePublic(keySpec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package com.skycrate.backend.skycrateBackend.utils;
|
|
||||||
|
|
||||||
import javax.crypto.*;
|
|
||||||
import java.security.*;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
|
|
||||||
public class RSAKeyUtil {
|
|
||||||
|
|
||||||
// Generate RSA Key Pair
|
|
||||||
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
|
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
|
|
||||||
generator.initialize(2048); // Key size
|
|
||||||
return generator.generateKeyPair();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert byte array to PublicKey
|
|
||||||
public static PublicKey getPublicKeyFromBytes(byte[] publicKeyBytes) throws Exception {
|
|
||||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes);
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
return keyFactory.generatePublic(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert byte array to PrivateKey
|
|
||||||
public static PrivateKey getPrivateKeyFromBytes(byte[] privateKeyBytes) throws Exception {
|
|
||||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
|
||||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
|
||||||
return keyFactory.generatePrivate(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encrypt data using RSA (with padding)
|
|
||||||
public static byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // Specify padding
|
|
||||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
|
||||||
return cipher.doFinal(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decrypt data using RSA (with padding)
|
|
||||||
public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
|
|
||||||
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // Specify padding
|
|
||||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
|
||||||
return cipher.doFinal(encryptedData);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate AES Key (128, 192, or 256 bits)
|
|
||||||
public static SecretKey generateAESKey(int keySize) throws NoSuchAlgorithmException {
|
|
||||||
if (keySize != 128 && keySize != 192 && keySize != 256) {
|
|
||||||
throw new IllegalArgumentException("Invalid AES key size. Must be 128, 192, or 256 bits.");
|
|
||||||
}
|
|
||||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
|
||||||
keyGenerator.init(keySize); // Specify the key size
|
|
||||||
return keyGenerator.generateKey();
|
|
||||||
}
|
|
||||||
//
|
|
||||||
// // Encrypt AES Key using RSA
|
|
||||||
// public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception {
|
|
||||||
// return encrypt(aesKey.getEncoded(), publicKey); // Encrypt the AES key using RSA
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Decrypt AES Key using RSA
|
|
||||||
// public static SecretKey decryptAESKey(byte[] encryptedAESKey, PrivateKey privateKey, int keySize) throws Exception {
|
|
||||||
// byte[] decryptedKey = decrypt(encryptedAESKey, privateKey); // Decrypt with RSA
|
|
||||||
// // Ensure that the decrypted key length matches the expected AES key size
|
|
||||||
// if (decryptedKey.length != keySize / 8) {
|
|
||||||
// throw new IllegalArgumentException("Decrypted key size does not match expected AES key size.");
|
|
||||||
// }
|
|
||||||
// return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES"); // Convert to AES Key
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static byte[] encryptAESKey(SecretKey aesKey, PublicKey publicKey) throws Exception {
|
|
||||||
return encrypt(aesKey.getEncoded(), publicKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SecretKey decryptAESKey(byte[] encryptedAESKey, PrivateKey privateKey, int keySize) throws Exception {
|
|
||||||
byte[] decryptedKey = decrypt(encryptedAESKey, privateKey);
|
|
||||||
return new SecretKeySpec(decryptedKey, 0, decryptedKey.length, "AES");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,15 +3,13 @@ spring.application.name=skycrateBackend
|
|||||||
spring.servlet.multipart.max-file-size=1000MB
|
spring.servlet.multipart.max-file-size=1000MB
|
||||||
spring.servlet.multipart.max-request-size=1000MB
|
spring.servlet.multipart.max-request-size=1000MB
|
||||||
|
|
||||||
spring.servlet.multipart.enabled=true
|
|
||||||
|
|
||||||
security.jwt.secret-key=3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b
|
security.jwt.secret-key=3cfa76ef14937c1c0ea519f8fc057a80fcd04a7420f8e8bcd0a7567c272e007b
|
||||||
security.jwt.expiration-time=3600000
|
security.jwt.expiration-time=3600000
|
||||||
|
|
||||||
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
|
||||||
spring.datasource.username=skycrateDB
|
spring.datasource.username=kshitij
|
||||||
spring.datasource.password=${MYSQL_PASSWORD}
|
spring.datasource.password=loa_dngLLA8729
|
||||||
spring.datasource.url=jdbc:mysql://db:3306/skycrate
|
spring.datasource.url=jdbc:mysql://192.168.29.55:3306/skycrate
|
||||||
|
|
||||||
spring.jpa.hibernate.ddl-auto=update
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
spring.jpa.show-sql=true
|
spring.jpa.show-sql=true
|
||||||
@@ -19,7 +17,7 @@ spring.jpa.properties.hibernate.format_sql=true
|
|||||||
spring.jpa.open-in-view=false
|
spring.jpa.open-in-view=false
|
||||||
logging.level.org.springframework.security.config.annotation.authentication.configuration.InitializeUserDetailsBeanManagerConfigurer=ERROR
|
logging.level.org.springframework.security.config.annotation.authentication.configuration.InitializeUserDetailsBeanManagerConfigurer=ERROR
|
||||||
|
|
||||||
server.port=8081
|
server.port=8080
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user