I have an MVC 5 application that allows users to download files that are stored in the database. I am using the FileContentResult action method to do this.
I can restrict access to this method throughout the application, but a smart user can figure out the action URL and paste something like this (localhost:50000/Home/FileDownload?id=13) into their browser and have access to download any file by just changing the parameter.
I want to restrict users from doing this. Only allow the Administrator role AND users that have a specific permission that can only be determined by a database call to download files.
What I am looking for is that If an user uses the URL to download a file and does not have the proper permissions, I want to redirect the user with a message.
I would like to do something like the code below or similar, but I get the following error: Cannot implicitly convert type 'System.Web.Mvc.RedirectToRouteResult' to 'System.Web.Mvc.FileContentResult'
I understand that I can not use return RedirectToAction("Index") here, just looking for some ideas on how to handle this problem.
public FileContentResult FileDownload(int id)
{
//Check user has file download permission
bool UserHasPermission = Convert.ToInt32(context.CheckUserHasFileDownloadPermission(id)) == 0 ? false : true;
if (User.IsInRole("Administrator") || UserHasPermission)
{
//declare byte array to get file content from database and string to store file name
byte[] fileData;
string fileName;
//create object of LINQ to SQL class
//using LINQ expression to get record from database for given id value
var record = from p in context.UploadedFiles
where p.Id == id
select p;
//only one record will be returned from database as expression uses condtion on primary field
//so get first record from returned values and retrive file content (binary) and filename
fileData = (byte[])record.First().FileData.ToArray();
fileName = record.First().FileName;
//return file and provide byte file content and file name
return File(fileData, "text", fileName);
}
else
{
TempData["Message"] = "Record not found";
return RedirectToAction("Index");
}
}