Merge branch 'master' of https://github.com/Devoalda/Safe_Share
This commit is contained in:
commit
7b9bf1dada
|
@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
|
||||||
function ShareFile() {
|
function ShareFile() {
|
||||||
const [file, setFile] = useState(null);
|
const [file, setFile] = useState(null);
|
||||||
const [passcode, setPasscode] = useState('');
|
const [passcode, setPasscode] = useState('');
|
||||||
|
const [ttl, setTtl] = useState('');
|
||||||
const [shareableLink, setShareableLink] = useState('');
|
const [shareableLink, setShareableLink] = useState('');
|
||||||
const [notification, setNotification] = useState('');
|
const [notification, setNotification] = useState('');
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ function ShareFile() {
|
||||||
if (file) {
|
if (file) {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('file', file);
|
formData.append('file', file);
|
||||||
//formData.append('ttl', "60");
|
formData.append('ttl', ttl * 24 * 60 * 60);
|
||||||
|
|
||||||
// Send POST request to the backend API using Axios
|
// Send POST request to the backend API using Axios
|
||||||
axios
|
axios
|
||||||
|
@ -28,7 +29,10 @@ function ShareFile() {
|
||||||
// If data is an array, take the first item
|
// If data is an array, take the first item
|
||||||
if (Array.isArray(data)) {
|
if (Array.isArray(data)) {
|
||||||
const passcode = data[0].key;
|
const passcode = data[0].key;
|
||||||
|
const baseUrl = 'http://localhost:8000/api/files/';
|
||||||
|
|
||||||
setPasscode(passcode);
|
setPasscode(passcode);
|
||||||
|
setShareableLink(baseUrl + passcode);
|
||||||
// Copy the passcode to the clipboard
|
// Copy the passcode to the clipboard
|
||||||
navigator.clipboard.writeText(passcode).then(() => {
|
navigator.clipboard.writeText(passcode).then(() => {
|
||||||
// Show a notification
|
// Show a notification
|
||||||
|
@ -40,8 +44,6 @@ function ShareFile() {
|
||||||
// Handle errors here
|
// Handle errors here
|
||||||
console.error('File upload failed', error);
|
console.error('File upload failed', error);
|
||||||
});
|
});
|
||||||
const baseUrl = 'http://localhost:3000/download/';
|
|
||||||
setShareableLink(baseUrl);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,7 +63,23 @@ function ShareFile() {
|
||||||
Back
|
Back
|
||||||
</Link>
|
</Link>
|
||||||
<h1 className="text-2xl font-bold mb-4">Share a file with others!</h1>
|
<h1 className="text-2xl font-bold mb-4">Share a file with others!</h1>
|
||||||
|
|
||||||
|
{/* TTL Input */}
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-sm font-medium text-gray-700">
|
||||||
|
TTL (in days):
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
min="1"
|
||||||
|
value={ttl}
|
||||||
|
onChange={(e) => setTtl(e.target.value)}
|
||||||
|
className="mt-1 p-2 w-full border rounded-md focus:ring focus:ring-opacity-50"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<FileUploader handleChange={handleFileUpload} name="file" />
|
<FileUploader handleChange={handleFileUpload} name="file" />
|
||||||
|
|
||||||
{passcode && (
|
{passcode && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<label className="block text-sm font-medium text-gray-700">
|
<label className="block text-sm font-medium text-gray-700">
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import threading
|
import threading
|
||||||
import uuid
|
import uuid
|
||||||
import os
|
import os
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from safeshare.safeshare_vdb.client import Client
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from rest_framework.decorators import api_view
|
from rest_framework.decorators import api_view
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -43,11 +45,32 @@ def manage_items(request):
|
||||||
# Define the path to save the file locally
|
# Define the path to save the file locally
|
||||||
save_path = os.path.join(settings.MEDIA_ROOT, filename)
|
save_path = os.path.join(settings.MEDIA_ROOT, filename)
|
||||||
|
|
||||||
|
# Hash the file
|
||||||
|
hasher = hashlib.sha256()
|
||||||
|
|
||||||
# Save the file locally
|
# Save the file locally
|
||||||
with open(save_path, 'wb') as destination:
|
with open(save_path, 'wb') as destination:
|
||||||
for chunk in file.chunks():
|
for chunk in file.chunks():
|
||||||
|
hasher.update(chunk)
|
||||||
destination.write(chunk)
|
destination.write(chunk)
|
||||||
|
|
||||||
|
# Get the hash signature
|
||||||
|
hash_signature = hasher.hexdigest()
|
||||||
|
print(f"Hash signature: {hash_signature}")
|
||||||
|
|
||||||
|
# Call RPC For virus scan
|
||||||
|
client = Client()
|
||||||
|
result = client.CheckFile(hash_signature)
|
||||||
|
|
||||||
|
# If infected, delete the file and return an error
|
||||||
|
if result:
|
||||||
|
response = {
|
||||||
|
'msg': f"File {filename} is infected with a virus"
|
||||||
|
}
|
||||||
|
os.remove(save_path)
|
||||||
|
responses.append(response)
|
||||||
|
return Response(responses, status=400)
|
||||||
|
|
||||||
# Store the file path in the cache with the provided TTL
|
# Store the file path in the cache with the provided TTL
|
||||||
cache.set(key,
|
cache.set(key,
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,16 +8,16 @@ class Client:
|
||||||
self.stub = pb2_grpc.Dynamo_DBStub(self.channel)
|
self.stub = pb2_grpc.Dynamo_DBStub(self.channel)
|
||||||
|
|
||||||
def CheckFile(self, sha_256_id: str):
|
def CheckFile(self, sha_256_id: str):
|
||||||
response = self.stub.CheckFile(pb2.Request(file_hash=sha_256_id))
|
response = self.stub.CheckHash(pb2.Request(file_hash=sha_256_id))
|
||||||
print(response)
|
return response.is_exist
|
||||||
|
|
||||||
def UpdateFile(self, sha_256_id: str):
|
def UpdateFile(self, sha_256_id: str):
|
||||||
response = self.stub.UpdateFile(pb2.Request(file_hash=sha_256_id))
|
response = self.stub.UpdateHash(pb2.Request(file_hash=sha_256_id))
|
||||||
print(response)
|
return response.is_exist
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
client = Client()
|
client = Client()
|
||||||
id = "15e4313dddb45875ed67d1ab25f1f5b76f0b3a23e4fa9308c521e3fb30068028"
|
id = "15e4313dddb45875ed67d1ab25f1f5b76f0b3a23e4fa9308c521e3fb30068028"
|
||||||
client.CheckFile(id)
|
print(client.CheckFile(id))
|
||||||
client.UpdateFile(id)
|
# client.UpdateFile(id)
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
API_TOKEN=
|
|
@ -4,6 +4,9 @@ import re
|
||||||
import grpc
|
import grpc
|
||||||
import dynamo_pb2 as pb2
|
import dynamo_pb2 as pb2
|
||||||
import dynamo_pb2_grpc as pb2_grpc
|
import dynamo_pb2_grpc as pb2_grpc
|
||||||
|
import environ
|
||||||
|
import os
|
||||||
|
import requests
|
||||||
|
|
||||||
import boto3 as boto # 1.28.68
|
import boto3 as boto # 1.28.68
|
||||||
|
|
||||||
|
@ -13,23 +16,68 @@ sha256_table = dynamodb.Table('safeshare_sha256')
|
||||||
sha1_table = dynamodb.Table('safeshare_sha1')
|
sha1_table = dynamodb.Table('safeshare_sha1')
|
||||||
md5_table = dynamodb.Table('safeshare_md5')
|
md5_table = dynamodb.Table('safeshare_md5')
|
||||||
|
|
||||||
|
# TotalVirus API key
|
||||||
|
environ.Env.read_env('./.env')
|
||||||
|
api = environ.Env().str('API_TOKEN')
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"accept": "application/json",
|
||||||
|
"x-apikey": api
|
||||||
|
}
|
||||||
|
|
||||||
# hash
|
# hash
|
||||||
hex_pattern = re.compile("^[a-fA-F0-9]+$")
|
hex_pattern = re.compile("^[a-fA-F0-9]+$")
|
||||||
|
|
||||||
|
|
||||||
|
def upload(hash_val):
|
||||||
|
if not hex_pattern.match(hash_val):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
length = len(hash_val)
|
||||||
|
if length == 64:
|
||||||
|
sha256_table.put_item(Item={'sha256': hash_val})
|
||||||
|
elif length == 40:
|
||||||
|
sha1_table.put_item(Item={'sha1': hash_val})
|
||||||
|
elif length == 32:
|
||||||
|
md5_table.put_item(Item={'md5': hash_val})
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def scan(hash_val):
|
||||||
|
url = "https://www.virustotal.com/api/v3/files/" + hash_val
|
||||||
|
response = requests.get(url, headers=headers)
|
||||||
|
if response.status_code == 200:
|
||||||
|
data = response.json()["data"]
|
||||||
|
return data["attributes"]["last_analysis_stats"]["malicious"] > 0
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_sha256(sha256):
|
def check_sha256(sha256):
|
||||||
response = sha256_table.get_item(Key={'sha256': sha256})
|
response = sha256_table.get_item(Key={'sha256': sha256})
|
||||||
return 'Item' in response
|
if "Item" not in response:
|
||||||
|
return upload(sha256) if scan(sha256) else False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_sha1(sha1):
|
def check_sha1(sha1):
|
||||||
response = sha1_table.get_item(Key={'sha1': sha1})
|
response = sha1_table.get_item(Key={'sha1': sha1})
|
||||||
return 'Item' in response
|
if "Item" not in response:
|
||||||
|
return upload(sha1) if scan(sha1) else False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def check_md5(md5):
|
def check_md5(md5):
|
||||||
response = md5_table.get_item(Key={'md5': md5})
|
response = md5_table.get_item(Key={'md5': md5})
|
||||||
return 'Item' in response
|
if "Item" not in response:
|
||||||
|
return upload(md5) if scan(md5) else False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
class Dynamo(pb2_grpc.Dynamo_DBServicer):
|
class Dynamo(pb2_grpc.Dynamo_DBServicer):
|
||||||
|
@ -48,21 +96,7 @@ class Dynamo(pb2_grpc.Dynamo_DBServicer):
|
||||||
return pb2.Response(is_exist=False)
|
return pb2.Response(is_exist=False)
|
||||||
|
|
||||||
def UpdateHash(self, request, context):
|
def UpdateHash(self, request, context):
|
||||||
if not hex_pattern.match(request.file_hash):
|
return pb2.Response(is_exist=upload(request.file_hash))
|
||||||
return pb2.Response(is_exist=False)
|
|
||||||
else:
|
|
||||||
length = len(request.file_hash)
|
|
||||||
if length == 64:
|
|
||||||
sha256_table.put_item(Item={'sha256': request.file_hash})
|
|
||||||
return pb2.Response(is_exist=True)
|
|
||||||
elif length == 40:
|
|
||||||
sha1_table.put_item(Item={'sha1': request.file_hash})
|
|
||||||
return pb2.Response(is_exist=True)
|
|
||||||
elif length == 32:
|
|
||||||
md5_table.put_item(Item={'md5': request.file_hash})
|
|
||||||
return pb2.Response(is_exist=True)
|
|
||||||
else:
|
|
||||||
return pb2.Response(is_exist=False)
|
|
||||||
|
|
||||||
|
|
||||||
def serve():
|
def serve():
|
||||||
|
|
Loading…
Reference in New Issue