Skip to content

Commit

Permalink
Merge pull request #510 from COS301-SE-2023/frontend/files2
Browse files Browse the repository at this point in the history
Frontend/files2
  • Loading branch information
ChrisMitt authored Oct 17, 2023
2 parents fe6b513 + ee3b8ea commit aee7b7a
Show file tree
Hide file tree
Showing 9 changed files with 336 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.fragile.infosafe.primary.config;

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class StorageConfig {

@Value("${AWS_ACCESS_KEY_ID}")
Expand All @@ -19,8 +22,14 @@ public class StorageConfig {
private String secretKey;

@Bean
public AmazonS3 generateS3Client(){
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials)).withRegion("us-east-1").build();
public AmazonS3 s3Client(){
AmazonS3 s3 = AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
.withRegion("us-east-1")
.build();

log.info("Amazon S3 client initialized: {}", s3);

return s3;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

@RestController
@Slf4j
@RequestMapping("api/storage")
public class StorageController {

private StorageService service;
private StorageService service = new StorageService();

@PostMapping("/upload")
public ResponseEntity<String> uploadFile(@RequestParam(value = "file") MultipartFile file){
return new ResponseEntity<>(service.uploadFile(file), HttpStatus.OK);
@PostMapping("/upload/{dsid}")
public ResponseEntity<String> uploadFile(@RequestParam(value = "file") MultipartFile file, @PathVariable String dsid) throws IOException {
return new ResponseEntity<>(service.uploadFile(file, dsid), HttpStatus.OK);
}

@GetMapping("/download/{fileName}")
Expand All @@ -37,4 +40,9 @@ public ResponseEntity<ByteArrayResource> downloadFile(@PathVariable String fileN
public ResponseEntity<String> deleteFile(@PathVariable String fileName){
return new ResponseEntity<>(service.deleteFile(fileName), HttpStatus.OK);
}

@GetMapping("/list")
public List<String> getAllFileNames(){//@RequestParam String bucketName) {
return service.getAllFileNames();
}
}
Original file line number Diff line number Diff line change
@@ -1,42 +1,72 @@
package com.fragile.infosafe.primary.service;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.utils.IoUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

@Service
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class StorageService {

@Value("${AWS_S3_BUCKET_NAME}")
private String bucketName;
//@Value("${AWS_S3_BUCKET_NAME}")
private String bucketName = System.getenv("AWS_S3_BUCKET_NAME");

//@Value("${AWS_ACCESS_KEY_ID}")
private String accessKey = System.getenv("AWS_ACCESS_KEY_ID");

//@Value("${AWS_SECRET_ACCESS_KEY}")
private String secretKey = System.getenv("AWS_SECRET_ACCESS_KEY");

//Persisting to AWS S3
@Autowired
private AmazonS3 s3Client;
public String uploadFile(MultipartFile file){
//@Autowired
private AmazonS3 s3Client = initializeS3Client();

public AmazonS3 initializeS3Client(){
return s3Client = AmazonS3ClientBuilder.standard()
.withRegion("us-east-1")
.withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey)))
.build();
}




public String uploadFile(MultipartFile file, String dsid) throws IOException {

Date date = new Date();

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
String fileDate = formatter.format(date);
File fileObj = convertMultiPartFiletoFile(file);
String fileName = System.currentTimeMillis() + file.getOriginalFilename();
s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj));
int id = Integer.parseInt(dsid);

String fileName = fileDate + "-DatascopeID=" + id + "-" + file.getOriginalFilename();
try {
this.s3Client.putObject(new PutObjectRequest(bucketName, fileName, fileObj));
}
catch (AmazonS3Exception e){
log.error("Unable to upload file", e);
}
fileObj.delete();

return "File Uploaded: " + fileName;
}

public byte[] dowloadFile(String fileName){

S3Object s3Object = s3Client.getObject(bucketName, fileName);
S3Object s3Object = this.s3Client.getObject(bucketName, fileName);
S3ObjectInputStream inputStream = s3Object.getObjectContent();

try {
Expand All @@ -50,10 +80,30 @@ public byte[] dowloadFile(String fileName){
}

public String deleteFile(String fileName){
s3Client.deleteObject(bucketName, fileName);
this.s3Client.deleteObject(bucketName, fileName);
return fileName + " removed from S3 ...";
}

public List<String> getAllFileNames() {
List<String> fileNames = new ArrayList<>();

ObjectListing objectListing = s3Client.listObjects(bucketName);

for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
fileNames.add(objectSummary.getKey());
}

// If the bucket contains more than 1000 objects, you may need to paginate through results.
while (objectListing.isTruncated()) {
objectListing = s3Client.listNextBatchOfObjects(objectListing);
for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
fileNames.add(objectSummary.getKey());
}
}

return fileNames;
}

//Converting multipart file to normal file
private File convertMultiPartFiletoFile(MultipartFile file){

Expand Down
168 changes: 161 additions & 7 deletions frontend/infosafe_frontend/src/components/FilePopup.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,162 @@
import "../styling/FilePopup.css"
import Popup from "reactjs-popup";
import {IoArrowBackOutline} from "react-icons/io5";
import React from "react";
import React, {useEffect, useState} from "react";
import Dropdown from "react-dropdown";
import {useGetFiles} from "./getData/getFiles";

// const FILES = [];

export const FilePopup = ({ popupOpen, popupClose, datascope }) => {
const [selectedFile, setSelectedFile] = useState(null);
const {showFile, loading, fetchAllFiles} = useGetFiles();
let FILES = [];

useEffect(() => {
fetchAllFiles();
}, []);


showFile.map((data) =>
FILES.push(data)
);

let fileArray = [];
for (let i=0; i<FILES.length; i++){
let fileID = FILES[i].substring(23);
fileID = fileID.slice(0, 2);

if(fileID[fileID.length-1] === "-"){
fileID = fileID.substring(0, fileID.length-1);
}
const int = parseInt(fileID);
if(int === datascope.data_scope_id){
fileArray.push(FILES[i]);
}
}
FILES = fileArray;

if (loading === true){
FILES[0] = "Files Loading.....";
}
else if (FILES.length === 0)
{
FILES[0] = "No Files added yet.";
}

const handleFileChange = (event) => {
setSelectedFile(event.target.files[0]);
};

const handleFileUpload = () => {
if (!selectedFile) {
alert("Please select a file to upload.");
return;
}

const formData = new FormData();
selectedFile.title = "help";
formData.append("file", selectedFile);

fetch(`http://localhost:8080/api/storage/upload/${datascope.data_scope_id}`, {
method: "POST",
headers: {
Authorization: "Bearer " + sessionStorage.getItem('accessToken')
},
body: formData,
})
.then((response) => {
if (response.ok) {
// Handle the response as needed
popupClose();
return response.text();
} else {
//console.log(response);
throw new Error("File upload failed");
}
})
};

const handleFileDelete = () => {
// Check if a file has been selected for deletion
if (!selectedFile) {
alert("Please select a file to delete.");
return;
}

// Determine the file name or identifier that you want to delete (you may need to pass it to the server).
const fileToDelete = selectedFile.value; // Adjust this based on your server's requirements
fetch(`http://localhost:8080/api/storage/delete/${fileToDelete}`, {
method: "DELETE",
headers: {
Authorization: "Bearer " + sessionStorage.getItem('accessToken')
},
})
.then((response) => {
if (response.ok) {
// Handle the success case (file deleted) as needed
alert("File deleted successfully");
setSelectedFile(null); // Clear the selected file
popupClose();
// You can also update your UI or perform other actions here
} else {
throw new Error("File deletion failed");
}
})
.catch((error) => {
// Handle any errors that occur during the deletion
console.error("File deletion error: ", error);
});
};

const handleFileDownload = () => {
// Check if a file has been selected for download
if (!selectedFile) {
alert("Please select a file to download.");
return;
}
const fileToDownload = selectedFile.value;
fetch(`http://localhost:8080/api/storage/download/${fileToDownload}`, {
method: "GET",
headers: {
Authorization: "Bearer " + sessionStorage.getItem('accessToken')
},
})
.then(async (response) => {
if (response.ok) {
alert("File downloaded successfully");

// Get the response body as a blob
const blob = await response.blob();
// Create an object URL for the response body
const objectUrl = URL.createObjectURL(blob);

// Create an invisible anchor element for the download
const anchor = document.createElement("a");
anchor.href = objectUrl;
anchor.target = "_blank";
anchor.download = "Privacy_Policy.pdf";

// Trigger a click event on the anchor to start the download
anchor.click();

// Revoke the object URL after the download is complete
URL.revokeObjectURL(objectUrl);

setSelectedFile(null);
console.log(response);

popupClose();
} else {
throw new Error("File deletion failed");
}
})
.catch((error) => {
// Handle any errors that occur during the deletion
console.error("File deletion error: ", error);
});
};

const FILES = ['FILE1','FILE2','FILE3'];
export const FilePopup = ({popupOpen,popupClose,datascope}) =>{
return (
<Popup open={popupOpen} closeOnDocumentClick={false} position="center center">
<div className="fileOverlay">
Expand All @@ -22,18 +173,21 @@ export const FilePopup = ({popupOpen,popupClose,datascope}) =>{
value={FILES[0]}
className="fileDropdown"
name="createRiskProbabilityDropdown"
//onChange={}
onChange={(selectedOption) => setSelectedFile(selectedOption)}
/>
<div className="fileButtonsDiv">
<button className="fileDownload">
<button className="fileDownload" onClick={handleFileDownload}>
Download
</button>
<button className="fileDelete">
<button className="fileDelete" onClick={handleFileDelete}>
Delete
</button>
</div>
<p className="uploadLabel">Upload File</p>
<input type="file" className="fileUpload"/>
<input type="file" className="fileUpload" onChange={handleFileChange}/>
<button className="fileUploadButton" onClick={handleFileUpload}>
Upload
</button>
</div>
</div>
</div>
Expand Down
Loading

0 comments on commit aee7b7a

Please sign in to comment.