public byte[] GetDecryptedAssignment(Guid submissionId)
        {
            SubmissionViewModel submission = _assignmentsService.GetSubmission(submissionId);

            FileStream fs = new FileStream(submission.FilePath, FileMode.Open, FileAccess.Read);

            MemberViewModel teacher = _membersService.GetMember(submission.Member.TeacherEmail);

            byte[] key = CryptographicHelper.AsymmetricDecrypt(
                Convert.FromBase64String(submission.SymmetricKey), teacher.PrivateKey);

            byte[] iv = CryptographicHelper.AsymmetricDecrypt(
                Convert.FromBase64String(submission.SymmetricIV), teacher.PrivateKey);


            MemoryStream ms = new MemoryStream();

            fs.CopyTo(ms);

            byte[] encryptedAssignment = ms.ToArray();

            byte[] decryptedAssignment = CryptographicHelper.SymmetricDecrypt(
                encryptedAssignment,
                key, iv);

            return(decryptedAssignment);
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            AssignmentsController controller = (AssignmentsController)context.Controller;
            ILogger logger = controller.GetLogger();

            try
            {
                var id           = Guid.Parse(CryptographicHelper.SymmetricDecrypt(context.ActionArguments["id"].ToString()));
                var loggedInUser = context.HttpContext.User.Identity.Name;

                IAssignmentsService assignmentsService = (IAssignmentsService)context.HttpContext.RequestServices.GetService(typeof(IAssignmentsService));


                if (loggedInUser != assignmentsService.GetSubmission(id).Member.Email&& !context.HttpContext.User.IsInRole("Teacher"))
                {
                    IPHostEntry iphostinfo = Dns.GetHostEntry(Dns.GetHostName());

                    string ipaddress = Convert.ToString(iphostinfo.AddressList.FirstOrDefault(address => address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));

                    logger.LogInformation(loggedInUser + " on IP " + ipaddress + " tried to access submission with id " + id + ". Access was denied");

                    context.Result = new UnauthorizedObjectResult("Access Denied");
                }
            }
            catch (Exception ex)
            {
                logger.LogInformation("Bad request when user tried to access a file");
                context.Result = new BadRequestObjectResult("Bad Request");
            }

            base.OnActionExecuting(context);
        }
        public IActionResult ViewSubmission(string id)
        {
            Guid decryptedId = Guid.Parse(
                HttpUtility.UrlDecode(
                    CryptographicHelper.SymmetricDecrypt(id)));

            ViewSubmissionViewModel submission = new ViewSubmissionViewModel();

            submission.Submission = _assignmentsService.GetSubmission(decryptedId);

            if (User.IsInRole("Teacher"))
            {
                var checks = CheckForAuthandInt(decryptedId);

                if (checks.Item2 == false)
                {
                    ViewData["isAuthentic"] = 0;
                }
            }

            var comments = _assignmentsService.GetComments(decryptedId);

            ViewBag.Comments = comments;
            return(View(submission));
        }
        public IActionResult ViewSubmissions(string assigmmentId)
        {
            Guid decryptedAssignmentId = Guid.Parse(
                HttpUtility.UrlDecode(
                    CryptographicHelper.SymmetricDecrypt(assigmmentId)));

            var list = _assignmentsService.GetSubmissions(decryptedAssignmentId);

            return(View(list));
        }
        public IActionResult SubmitAssignment(string id)
        {
            Guid decryptedId = Guid.Parse(
                HttpUtility.UrlDecode(CryptographicHelper.SymmetricDecrypt(id)));

            CookieOptions cookieOptions = new CookieOptions();

            Response.Cookies.Append("Assignment", id, cookieOptions);
            var assignment = _assignmentsService.GetAssignment(decryptedId);

            ViewBag.Assignment = assignment;

            return(View());
        }
        public IActionResult Delete(string id)
        {
            try
            {
                Guid decryptedId = Guid.Parse(
                    HttpUtility.UrlDecode(CryptographicHelper.SymmetricDecrypt(id)));
                _assignmentsService.DeleteAssignment(decryptedId);
                ViewData["info"] = "Assignment deleted";
            }catch (Exception ex)
            {
                ViewData["warning"] = "Error deleting assignment";
            }


            return(RedirectToAction("Index"));
        }
        public IActionResult ViewFile(string id)
        {
            Guid decryptedId = Guid.Parse(HttpUtility.UrlDecode(CryptographicHelper.SymmetricDecrypt(id)));

            byte[] decryptedAssignment = GetDecryptedAssignment(decryptedId);

            IPHostEntry iphostinfo = Dns.GetHostEntry(Dns.GetHostName());

            string ipaddress = Convert.ToString(iphostinfo.AddressList.FirstOrDefault(address => address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork));


            if (User.IsInRole("Teacher"))
            {
                _logger.LogInformation("Teacher " + User.Identity.Name + " on IP " + ipaddress + " accessed file of submission " + decryptedId + " on " + DateTime.Now);
            }
            else if (User.IsInRole("Student"))
            {
                _logger.LogInformation("Student " + User.Identity.Name + " on IP " + ipaddress + " accessed file of submission " + decryptedId + " on " + DateTime.Now);
            }

            return(File(decryptedAssignment, "application/pdf"));
        }
        public Tuple <bool, bool> CheckForAuthandInt(Guid id)
        {
            bool isDistinct = true;
            bool isVerified = true;

            SubmissionViewModel submission = _assignmentsService.GetSubmission(id);

            var submissions = _assignmentsService.GetSubmissions(submission.Assignment.Id);

            MemberViewModel teacher = _membersService.GetMember(submission.Member.TeacherEmail);


            byte[] key = CryptographicHelper.AsymmetricDecrypt(
                Convert.FromBase64String(submission.SymmetricKey), teacher.PrivateKey);

            byte[] iv = CryptographicHelper.AsymmetricDecrypt(
                Convert.FromBase64String(submission.SymmetricIV), teacher.PrivateKey);

            foreach (SubmissionViewModel sub in submissions)
            {
                if (sub.FileHash == submission.FileHash && sub.Member.Email != submission.Member.Email)
                {
                    TempData["warning"] += "Assignment is identical to " + sub.Member.Email + "'s assignment!\n";
                    isDistinct           = false;
                }
            }

            if (!CryptographicHelper.VerifySignature(
                    CryptographicHelper.SymmetricDecrypt(
                        Convert.FromBase64String(submission.Signature), key, iv),
                    CryptographicHelper.Hash(GetDecryptedAssignment(id)),
                    submission.Member.PublicKey))
            {
                isVerified = false;
            }

            return(new Tuple <bool, bool>(isDistinct, isVerified));
        }
        public IActionResult SubmitAssignment(IFormFile file)
        {
            var assignment = _assignmentsService.GetAssignment(Guid.Parse(CryptographicHelper.SymmetricDecrypt(Request.Cookies["Assignment"])));

            ViewBag.Assignment = assignment;


            if (file != null)
            {
                Stream stream     = file.OpenReadStream();
                int    firstByte  = stream.ReadByte();
                int    secondByte = stream.ReadByte();
                int    thirdByte  = stream.ReadByte();
                int    fourthByte = stream.ReadByte();
                stream.Position = 0;


                //If the file passes the following check, a submission is created with user credentials
                if (firstByte == 37 && secondByte == 80 && thirdByte == 68 && fourthByte == 70 && Path.GetExtension(file.FileName) == ".pdf")
                {
                    SubmissionViewModel submission = new SubmissionViewModel();
                    submission.Member = _membersService.GetMember(User.Identity.Name);

                    Tuple <byte[], byte[]> keys = CryptographicHelper.GenerateKeys();


                    MemberViewModel teacher = _membersService.GetMember(submission.Member.TeacherEmail);

                    string encryptedKey = Convert.ToBase64String(CryptographicHelper.AsymmetricEncrypt(keys.Item1, teacher.PublicKey));

                    string encryptedIv = Convert.ToBase64String(CryptographicHelper.AsymmetricEncrypt(keys.Item2, teacher.PublicKey));


                    submission.SymmetricKey = encryptedKey;
                    submission.SymmetricIV  = encryptedIv;

                    submission.Assignment = _assignmentsService.GetAssignment(assignment.Id);


                    string absolutePath = _host.WebRootPath + @"\..\ProtectedFiles\";
                    string uniqueName   = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);

                    using (MemoryStream ms = new MemoryStream())
                    {
                        stream.CopyTo(ms);
                        ms.Position = 0;

                        submission.FileHash = Convert.ToBase64String(CryptographicHelper.Hash(ms.ToArray()));

                        var signature = CryptographicHelper.GenerateSignature(Convert.FromBase64String(submission.FileHash), submission.Member.PrivateKey);

                        submission.Signature = Convert.ToBase64String(CryptographicHelper.SymmetricEncrypt(
                                                                          signature,
                                                                          keys.Item1, keys.Item2));


                        System.IO.File.WriteAllBytes(absolutePath + uniqueName,
                                                     CryptographicHelper.SymmetricEncrypt(
                                                         ms.ToArray(),
                                                         keys.Item1,
                                                         keys.Item2
                                                         )
                                                     );
                    }

                    submission.FilePath = absolutePath + uniqueName;
                    _assignmentsService.AddSubmission(submission);

                    TempData["info"] = "File accepted";

                    return(RedirectToAction("index"));
                }
                else
                {
                    TempData["warning"] = "File is not valid, only PDF allowed";
                    return(View());
                }
            }
            else
            {
                TempData["warning"] = "Please upload a file";

                return(View());
            }
        }