tags:

views:

25

answers:

1

I want to have users be able to upload .pdf and images and restrict the access to these files based on user's privileges. Has anyone done something similar? The basic plan of attach I thought of is a controller checks if the user has privileges to view the document or file. If they have the privileges the document is retrieved and displayed.

My .htacces file would include

 #Removes access to the secure_files folder by users.
 RewriteCond %{REQUEST_URI} ^secure_files.*
 RewriteRule ^(.*)$ /index.php?/$1 [L]


    ------
    -SQL
    ------

    ------
    - create files table
    -----
    CREATE TABLE `files` (
    id INT NOT NULL AUTO_INCREMENT,
    file_name VARCHAR(50) NOT NULL,
    PRIMARY KEY('id')
    );

    ------
    - create files table
    -----
    CREATE TABLE `privileges` (
    uesr_id INT NOT NULL,
    file_id INT NOT NULL,
    );

    ------
    - create users table
    -----
    CREATE TABLE `users` (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    email VARCHAR(50) NOT NULL,
    password CHAR(40) NOT NULL,
    PRIMARY KEY('id')
    );

    /*
    * pseudo-Codeigniter code. I can edit this to make 
    * it pure PHP if that would be more helpful 
    *
    */
    public function get_user_files($filename)
    {
       //this is set during login
       $user_id = $this->session->userdata('user_id');

      //check to see if the user has privileges to access the file and gets the file name
      $query = $this->db->join('privileges','privileges.id = files.id')
                     ->select('files.file_name')
                     ->where('privileges.user_id',$user_id)
                     ->where('files.file_name',$file_name)
                     ->limit(1)
                     ->get('files');

    $file = $query->row()->files.file_name;

   if($file)
   {
    //user has privileges to access the file so include it

    //WHAT DO I DO HERE!?!
    //start Would this work?
    $handle = fopen($file, "rb");
    $data['file'] = fread($handle, filesize($file));
    fclose($handle);
    //end would this work?
   }
  $this->load->view('files',$data);
}
+1  A: 

An easy and secure solution would be to use the following schema. This will allow you to restrict access to the uploaded files and avoid the problem of uploading .php files. File sizes are capped by the size of a longblob which is 16mb in size.

CREATE TABLE `files` (
id INT NOT NULL AUTO_INCREMENT,
user_id INT NOT NULL,
file_name text NOT NULL,
file LONGBLOB NOT NULL,
PRIMARY KEY('id')
);

Here is php code to upload the file:

$user_file=file_get_contents($_FILES['user_file']['tmp_name']);
//Make the file binary safe
$user_file=mysql_real_escape_string($user_file);
$file_name=mysql_real_escape_string($_FILES['user_file']['name']);
$user_file=mysql_real_escape_string($user_file);

mysql_query("insert into files (user_id,file_name,file)values ("$_SESSION[user_id]","$file_name","$user_file");

Access control can be enforced by checking the user_id of a file. The content-type of a users file is easy to spoof so don't trust $_FILE[name][type], However this must be the correct type when you are letting the user download the file. For instance pdf should have this content-type. header('Content-type: application/pdf');

Rook
Oh the simple solutions are always the best! I have always agreed with people who say don't store images and documents in DB, but in this case the main concern in access control so it is the best solution. Thank you clearing this up.
John