Merge pull request #14 from AmanTahiliani/aman-malicious-reporting

Added changes for malicious user reporting
This commit is contained in:
Sahej Panag
2024-04-20 21:45:22 -04:00
committed by GitHub
11 changed files with 437 additions and 22 deletions

View File

@@ -0,0 +1,57 @@
# Generated by Django 4.2.11 on 2024-04-20 23:10
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("api", "0007_remove_file_points_file_downvotes_file_upvotes"),
]
operations = [
migrations.CreateModel(
name="UserReport",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("description", models.TextField(max_length=300)),
(
"file",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="file_report",
to="api.file",
),
),
(
"reporting_user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="user_report_generated",
to=settings.AUTH_USER_MODEL,
),
),
(
"user",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="user_report",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@@ -61,10 +61,28 @@ class File(models.Model):
upvotes = models.ManyToManyField(PeerUser, related_name="upvoted_file") upvotes = models.ManyToManyField(PeerUser, related_name="upvoted_file")
downvotes = models.ManyToManyField(PeerUser, related_name="downvoted_file") downvotes = models.ManyToManyField(PeerUser, related_name="downvoted_file")
@property @property
def points(self): def points(self):
return self.upvotes.count() - self.downvotes.count() return self.upvotes.count() - self.downvotes.count()
def __str__(self): def __str__(self):
return self.filename return self.filename
class UserReport(models.Model):
user = models.ForeignKey(
PeerUser, on_delete=models.SET_NULL, null=True, related_name="user_report"
)
reporting_user = models.ForeignKey(
PeerUser,
on_delete=models.SET_NULL,
null=True,
related_name="user_report_generated",
)
description = models.TextField(blank=False, null=False, max_length=300)
file = models.ForeignKey(
File, on_delete=models.CASCADE, null=True, related_name="file_report"
)
def __str__(self) -> str:
return f"{self.user}:{self.file}:{self.reporting_user}"

View File

@@ -46,4 +46,17 @@ class FileSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = File model = File
fields = "__all__" fields = [
"id",
"filename",
"points",
"original_author",
"peer_users",
"topic",
"professor",
"semester",
"course",
"created_at",
"upvotes",
"downvotes",
]

View File

@@ -65,6 +65,7 @@ urlpatterns = [
name="downvote-file", name="downvote-file",
), ),
path("api/files/<int:pk>/", views.FileDetailAPIView.as_view(), name="file-detail"), path("api/files/<int:pk>/", views.FileDetailAPIView.as_view(), name="file-detail"),
path("api/report_user/", views.ReportUserView.as_view(), name="report-user"),
path("api/register/", views.RegisterFile.as_view(), name="file-register"), path("api/register/", views.RegisterFile.as_view(), name="file-register"),
path("api/files/filter/", views.FileFilterView.as_view(), name="file-filter-view"), path("api/files/filter/", views.FileFilterView.as_view(), name="file-filter-view"),
] ]

View File

@@ -6,7 +6,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from api.utils.get_client_ip import get_client_ip from api.utils.get_client_ip import get_client_ip, PollMiddleware
from django.utils import timezone from django.utils import timezone

View File

@@ -1,3 +1,4 @@
from typing import Any
from django.utils import timezone from django.utils import timezone
@@ -16,3 +17,15 @@ def update_user_ip(request):
user.ip_address = ip_address user.ip_address = ip_address
user.last_poll = timezone.now() user.last_poll = timezone.now()
user.save() user.save()
class PollMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
print("Updating user last online and IP address")
update_user_ip(request)
response = self.get_response(request)
return response

View File

@@ -1,4 +1,4 @@
from api.models import Course, File, Professor, Semester, Topic, PeerUser from api.models import Course, File, Professor, Semester, Topic, PeerUser, UserReport
from api.serializers import ( from api.serializers import (
CourseSerializer, CourseSerializer,
FileSerializer, FileSerializer,
@@ -7,13 +7,13 @@ from api.serializers import (
TopicSerializer, TopicSerializer,
UserSerializer, UserSerializer,
) )
from datetime import datetime, timedelta from datetime import timedelta
from django.contrib.auth import authenticate from django.contrib.auth import authenticate
from django.db import transaction from django.db import transaction
from django.db.models import Count, Value, F, IntegerField
from django.utils import timezone from django.utils import timezone
from rest_framework import generics, status from rest_framework import generics, status
from rest_framework.authentication import TokenAuthentication from rest_framework.authentication import TokenAuthentication
from rest_framework.authtoken.models import Token
from rest_framework.permissions import IsAuthenticated from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
@@ -123,7 +123,7 @@ class UpvoteFile(APIView):
file.save() file.save()
return Response( return Response(
{"msg": f"Upvoted {file.filename}", "file_points": file.points}, {"msg": f"Upvoted {file.filename}", "file_points": file.points},
status=status.HTTP_200_OK, status=status.HTTP_200_OK,
) )
except Exception as e: except Exception as e:
print(f"Error: {str(e)}") print(f"Error: {str(e)}")
@@ -235,15 +235,6 @@ class RegisterFile(APIView):
) )
from django.utils import timezone
from datetime import timedelta
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import File, PeerUser
from .serializers import FileSerializer
class FileFilterView(APIView): class FileFilterView(APIView):
authentication_classes = [TokenAuthentication] authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated] permission_classes = [IsAuthenticated]
@@ -251,6 +242,7 @@ class FileFilterView(APIView):
def get(self, request, format=None): def get(self, request, format=None):
try: try:
# Extract filters from the query parameters # Extract filters from the query parameters
update_user_ip(request)
topic_id = request.query_params.get("topic") topic_id = request.query_params.get("topic")
professor_id = request.query_params.get("professor") professor_id = request.query_params.get("professor")
course_id = request.query_params.get("course") course_id = request.query_params.get("course")
@@ -291,19 +283,26 @@ class FileFilterView(APIView):
if semester_id: if semester_id:
queryset = queryset.filter(semester__id=semester_id) queryset = queryset.filter(semester__id=semester_id)
queryset = queryset.annotate(
upvote_count=Count("upvotes"), downvote_count=Count("downvotes")
).order_by(F("downvote_count") - F("upvote_count"))
# Filter files based on active peers in the past hour # Filter files based on active peers in the past hour
active_peer_ids = PeerUser.objects.filter( active_peer_ids = PeerUser.objects.filter(
last_poll__gte=timezone.now() - timedelta(hours=1) last_poll__gte=timezone.now() - timedelta(hours=1)
).values_list("id", flat=True) ).values_list("id", flat=True)
queryset = queryset.filter(peer_users__in=active_peer_ids).distinct() queryset = queryset.filter(peer_users__in=active_peer_ids).distinct()
# Sort files based on points column in descending order
queryset = queryset.order_by("-points")
# Serialize files
serializer = FileSerializer(queryset, many=True) serializer = FileSerializer(queryset, many=True)
# Loop through each serialized file to sort its peer_users # Loop through each serialized file to sort its peer_users
for file_data in serializer.data:
try:
serialized_data = serializer.data
print(serialized_data)
except Exception as e:
print(str(e))
for file_data in serialized_data:
print(file_data)
file_obj = File.objects.get(id=file_data["id"]) file_obj = File.objects.get(id=file_data["id"])
sorted_peer_users = sorted( sorted_peer_users = sorted(
file_obj.peer_users.all(), key=lambda x: x.points, reverse=True file_obj.peer_users.all(), key=lambda x: x.points, reverse=True
@@ -312,9 +311,72 @@ class FileFilterView(APIView):
sorted_peer_users, many=True sorted_peer_users, many=True
).data ).data
return Response(serializer.data) return Response(serialized_data)
except Exception as e: except Exception as e:
return Response( return Response(
{"error": f"Something went wrong: {str(e)}"}, {"error": f"Something went wrong: {str(e)}"},
status=status.HTTP_500_INTERNAL_SERVER_ERROR, status=status.HTTP_500_INTERNAL_SERVER_ERROR,
) )
class ReportUserView(APIView):
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request):
data = request.data
update_user_ip(request)
try:
assert "file_id" in data
assert "user_id" in data
assert "description" in data
except AssertionError as e:
return Response(
{"error": f"Missing Parameters. {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)
try:
file = File.objects.get(id=data["file_id"])
malicious_user = PeerUser.objects.get(id=data["user_id"])
reporting_user = request.user
description = data["description"]
except Exception as e:
return Response(
{"error": f"Missing/Incorrect Parameters. {str(e)}"},
status=status.HTTP_400_BAD_REQUEST,
)
existing_user_report_queryset = UserReport.objects.filter(
user=malicious_user, file=file, reporting_user=reporting_user
)
if len(existing_user_report_queryset):
existing_report = existing_user_report_queryset.first()
existing_report.description = description
existing_report.save()
return Response(
{
"msg": "User report already exists for this file. Updated description"
},
status=status.HTTP_208_ALREADY_REPORTED,
)
if (
file not in malicious_user.owned_files.all()
or file not in malicious_user.shared_files.all()
):
return Response(
{"error": "User does not own or host the file reported"},
status=status.HTTP_404_NOT_FOUND,
)
UserReport.objects.create(
user=malicious_user,
reporting_user=reporting_user,
file=file,
description=description,
)
malicious_user.points -= 1
malicious_user.save()
return Response({"msg": "Report Created!"}, status=status.HTTP_201_CREATED)

1
peer_temp/abcd.txt Normal file
View File

@@ -0,0 +1 @@
Hello Hi Test

View File

@@ -0,0 +1,45 @@
const SimplePeer = require('simple-peer');
// Function to act as the file host
function hostFile() {
const peer = new SimplePeer({ initiator: true });
peer.on('signal', data => {
console.log('Share this data with the peer who wants to download the file:');
console.log(JSON.stringify(data));
});
peer.on('connect', () => {
console.log('Peer connected. Sending file...');
const fileContent = 'This is the content of the file.';
peer.send(fileContent);
});
}
// Function to act as the file requester
function requestFile() {
const peer = new SimplePeer();
peer.on('signal', data => {
console.log('Share this data with the file host:');
console.log(JSON.stringify(data));
});
peer.on('connect', () => {
console.log('Peer connected. Waiting for file...');
});
peer.on('data', data => {
console.log(`File received: ${data}`);
});
}
// Decide whether to host the file or request it
const isHost = process.argv[2] === 'host';
if (isHost) {
hostFile();
} else {
requestFile();
}

View File

@@ -0,0 +1,84 @@
// // Requester Peer
// const net = require('net');
// // IP address and port of the other peer
// const otherPeerIP = 'other_peer_ip_address';
// const otherPeerPort = 12345; // Assuming this is the port the other peer is listening on
// // File ID to request
// const fileId = 'file123';
// // Create a TCP socket to connect to the other peer
// const client = new net.Socket();
// client.connect(otherPeerPort, otherPeerIP, () => {
// console.log('Connected to peer');
// // Send the file ID as a request
// client.write(fileId);
// });
// // Listen for data (the requested file) from the other peer
// client.on('data', (data) => {
// console.log('Received file:', data.toString());
// // Close the connection after receiving the file
// client.end();
// });
// // Handle connection errors
// client.on('error', (err) => {
// console.error('Connection error:', err);
// });
// Requester Peer
// const net = require('net');
// // IP address and port of the other peer
// const otherPeerIP = '127.0.0.1'; // Assuming both peers are running on the same machine
// const otherPeerPort = 12345;
// File ID to request
const fileId = 'abcd.txt';
// Create a TCP server to handle incoming requests from the other peer
// Requester Peer
const net = require('net');
// IP address and port of the receiving peer
const receiverIP = '127.0.0.1'; // Assuming both peers are running on the same machine
const receiverPort = 12345;
// File ID to request
// const fileId = 'file123';
// Create a TCP client to connect to the receiving peer server
const client = new net.Socket();
// Handle connection to the receiving peer
client.connect(receiverPort, receiverIP, () => {
console.log('Connected to receiving peer server');
// Send the file ID as a request to the receiving peer
client.write(fileId);
});
// Listen for data (the requested file) from the receiving peer
client.on('data', (data) => {
console.log('Received file:', data.toString());
// Close the connection after receiving the file
client.end();
});
// Handle connection errors
client.on('error', (err) => {
console.error('Connection error:', err);
});

121
peer_temp/temp_sender.js Normal file
View File

@@ -0,0 +1,121 @@
// // Receiving Peer
// const net = require('net');
// const fs = require('fs');
// // Port on which this peer will listen for requests
// const listenPort = 12345;
// // Mapping of file IDs to file paths
// const filesMap = {
// 'file123': '/path/to/file.txt',
// // Add more file IDs and corresponding file paths as needed
// };
// // Create a server to listen for incoming requests
// const server = net.createServer((socket) => {
// console.log('Peer connected');
// // Handle data (file ID) received from the requester peer
// socket.on('data', (data) => {
// const fileId = data.toString();
// console.log('Received request for file ID:', fileId);
// // Look up the file path based on the file ID
// const filePath = filesMap[fileId];
// if (filePath) {
// // Read the file and send its contents back to the requester
// fs.readFile(filePath, (err, fileData) => {
// if (err) {
// console.error('Error reading file:', err);
// socket.end();
// return;
// }
// // Send the file data to the requester
// socket.write(fileData);
// // Close the connection after sending the file
// socket.end();
// });
// } else {
// console.log('File ID not found');
// socket.end();
// }
// });
// });
// // Start listening for incoming connections
// server.listen(listenPort, () => {
// console.log('Peer server listening on port', listenPort);
// });
// // Handle server errors
// server.on('error', (err) => {
// console.error('Server error:', err);
// });
// Receiving Peer
const net = require('net');
const fs = require('fs');
// Port on which this peer will listen for requests
const listenPort = 12345;
// Mapping of file IDs to file paths
const filesMap = {
'abcd.txt': './abcd.txt',
// Add more file IDs and corresponding file paths as needed
};
// Create a TCP server to listen for incoming requests from other peers
const server = net.createServer((socket) => {
console.log('Receiving peer server connected');
// Handle data (file ID) received from the requester peer
socket.on('data', (data) => {
const fileId = data.toString();
console.log('Received request for file ID:', fileId);
// Look up the file path based on the file ID
const filePath = filesMap[fileId];
if (filePath) {
// Read the file and send its contents back to the requester
fs.readFile(filePath, (err, fileData) => {
if (err) {
console.error('Error reading file:', err);
socket.end();
return;
}
// Send the file data to the requester
socket.write(fileData);
// Close the connection after sending the file
socket.end();
});
} else {
console.log('File ID not found');
socket.end();
}
});
// Handle connection errors
socket.on('error', (err) => {
console.error('Connection error:', err);
});
});
// Start the server
server.listen(listenPort, () => {
console.log('Receiving peer server listening for incoming connections');
});
// Handle server errors
server.on('error', (err) => {
console.error('Server error:', err);
});