Laravel 5 Filesystem - Directory Permissions - laravel

I'm writing a Filesystem with a Login System at the moment in Laravel 5 and at the moment every User can create folders and upload files but, when I copy the path from the folder "A" from User "1" and log out and login with User "2" and paste the path in the Browser , I have acess to folder "A" from User "1".
I want that only the person which create the folder can open it and Upload files. I want a authentication via a User ID that checks if the currently user who is trying to open the folder/path is the creator and have the permission to do that.
public function mkdir(Request $request) {
$validator = Validator::make ( $request->all (), [
'dirname' => 'required|max:20'
] );
if ($validator->fails ( $request )) {
return redirect ( 'filesystem' )->withErrors ( $validator )->withInput ();
} else {
$id = Auth::user ()->id;
$dir = $request->dir . "/" . $request->dirname;

Trayer:
Because folder structure and ownership of the folder is set to users on the server, doing something like this without some sort of database is not possible. What I would suggest is something like what noodles_ftw suggests.
Create a table folderPermissions and in this folder, it would have a couple columns. owner, path
Owner would be the id of the user that created the folder, and path would be the path to the folder.
Next you would create some sort of middleware or other check to say baiscally the following
// get current user id
// get folders owned by that user
// if user is not allowed to view folder
// return an error letting them know
// continue to do what you need to do with the folder
This will allow you to run your checks and even alert that a user tried to access a folder that they were not allowed to access.
One of the other options you have here is to use the servers .htaccess and .htpasswd files. This would allow you to set up a list of users allowed to get into the folder. you would want to create these files when a user creates new folders. Use the users password and username from the database when generating the .htpasswd file for the user.
Find more information about this solution from the documentation

Related

Download all files in laravel media library without collection name

I'm trying to download all the uploads together under one user. If one user has uploaded under multiple collections, I want to download all uploads under all collections in one click as a zip file.
I tried without the collection name in getMedia function. But it's not getting my result.
$user = User::where('id',auth()->user()->id)->first();
$downloads = $user->getMedia();
return MediaStream::create('my-files.zip')->addMedia($downloads);
How can I download all files without the collection name in the media library in one click as a zip file?
I got the solution.
With collection name
$user = User::where('id',auth()->user()->id)->first();
$downloads = $user->getMedia('passport');
return MediaStream::create('myfiles.zip')->addMedia($downloads);
Without collection name
$user = User::where('id',auth()->user()->id)->first();
$downloads = ModelsMedia::where('model_id',$user->id)->get();
return MediaStream::create('myfiles.zip')->addMedia($downloads);

Laravel: How to prevent users loading files from outside the base path

I have a Laravel website and I have several routes that load the contents of images from Storage. I do this using the following code:
public function show_image($name) {
echo Storage::disk('images')->get($name);
}
I want to prevent users being able to set name to something like ../../../error.log. So I don't want users to escape the Storage directory. I have a few ideas on how to accomplish this however I want to know is there a best practice?
If you need just file name, not location, disallow them from inputting folder of any kind. Just cut the string on /.
end(preg_split("#/#", $name));
When you need to allow some folders and all of the contents, check the folder name, subfolder name, etc.
You could either keep a registry/index of the uploaded images, and only allow the user to show a image from that registry (e.g. an images database table).
Or you could do a scan of the directory, that you are allowing files from, and make sure, that the requested file is in that list.
public function show_image($name) {
$files = Storage::disk('images')->files();
if (! in_array($name, $files)) {
throw new \Exception('Requested file not found');
}
echo Storage::disk('images')->get($name);
}
(code untested)

Remove "/public" from file path in Laravel when linking public directory

I use Laravel of 5.7.25 version.
I have a symbolic link from public/storage to /storage/app/public.
I'm storing files in /storage/app/public/place-images directory.
I keep the path of stored file in table files which keeps all stored files. The file path would be public/images/some_hash.jpg.
Now I made a file resource, which is used when I'm getting files from my API. The file path retured from api equals public/images/some_hash.jpg. But instead I need it to be images/some_hash.jpg. However, in the table I prefer to keep real path of the file related to the storage folder. After all, I can keep files in AWS or somewhere else.
As far as I understand storage is the root of my disk. The $file->store() method includes public part of the file path.
I end up doing something like this:
// This is ImageResource file, Image model has File relation. One Image has one File
// TODO: Dirty hack
$path = $this->file->path; // This equals 'public/place-images/hash.jpg'
// Removing 'public' part
$charIndex = strpos($path, '/');
$path = substr($path, $charIndex + 1);
return [
'id' => $this->id,
'original_name' => $this->file->original_name,
url' => asset('storage/' . $path) // now we have /storage/place-images/some_hash.jpg which is correct
];
Is there anyway to avoid this dirty hack? I think I'm missing something obvious
storage is not the root of your disk. You can set the root for a disk in config\filesystems.php.
Default root for the public disk defined in config/filesystems.php is /storage/app/public so just store place-images/hash.jpg without public.
If you want to keep files from different disks in one table just add a field with a disk name to this table.

How to use storage_path() to view an image in laravel 4

I'm using storage_path() for storing uploaded images, but when I use it is pointing wrong on my page.
I use it like this {{ $data->thumbnail }} where $data came from the database and thumbnail comes as the string which used storage_path
Let us take a look at the default L4 application structure:
app // contains restricted server-side application data
app/storage // a writeable directory used by L4 and custom functions to store data ( i.e. log files, ... )
public // this directory is accessible for clients
If I were you, I would upload the file to the public directory directly:
Store image here: public_path() . 'img/filename.jpg'
Save the 'img/filename.jpg' in database
Generate the image URL with url('img/filename.jpg') => http://www.your-domain.com/img/filename.jpg
Hope this helps.
The storage_path function returns the path to the storage folder, which is inside the app folder --and outside the public folder-- so it's not directly accessible from the client, that's why your images are not being displayed. You can move them to the public folder path, or you could use a custom controller to handle the image requests, read the image from the storage folder and return the value.

Drupal 7 Importing images from a csv file

I have written a custom module to import users from a csv file into a drupal 7 database.
The csv file has a field for the users avatar that references an image in a directory.
The issue I'm having is with attaching the images to the user. So the image gets saved correctly in the pictures directory, the record is added the file_managed table, and the file id is added to the user's record. However when I go to edit the user via the drupal interface, the picture does not appear on that page.
The code I've got is below, any help would be awesome!
$userobj = user_load(1);
$file_temp = file_get_contents('/avatars/'.$importfile);
$file_temp = file_save_data($file_temp, 'public://pictures/' . $filename, FILE_EXISTS_RENAME);
$userobj->picture->fid = $file_temp->fid;
$userobj->status = 1;
user_save((object) array('uid' => $record->uid), (array) $userobj);
best way to get file path in d7 is
$path = file_default_scheme() . '://' ;
the path should now look something like public://
i had a mare saving in the users pictures folder but found it was a file permissions thing and had to chmod the folder

Resources