Understanding file storage and protecting contents Laravel 5 - laravel

I need help understanding Laravel's file storage system. I'm creating an app where I need to upload a users drivers license photo. This is obviously sensitive information. I would like to keep this image off of the internet unless an admin is viewing it. My understanding is that i have to save things to the public directory in the storage>app>public and create a symlink to the public>storage folder. I have this done and it's working fine. I save the path to the database and the program can display it, but I don't want things to be in the public folder if I can avoid it.
Is there any way to save an image/file to a private folder in the storage system then access it through the view? If I do this, does it keep that image "private" so that it's not stored in a cache somewhere beings that it's not in a "public" folder? Does the symlink protect files in the storage folder in the way I'm wanting or does it truly make all files available to the public?
Any help in understanding this would be appreciated.

What you've said is correct the files in storage/app/public is public. This is why you have to create a private directory, lets say storage/app/private, then upload your sensitive files here.
You may want to add a disks in your config/filesystems.php:
'private' => [
'driver' => 'local',
'root' => storage_path('app/private'),
],
If you want to access your private files. Create a route for this:
Route::get('/private-files/{file?}','FileController#get')->where('file', '(.*)');
Then in the FileController.php, you will have something like this (this is just an example, edit the code here to check if the user is admin):
<?php
namespace App\Http\Controllers;
use Auth;
use Storage;
use App\Http\Controllers\Controller;
class FileController extends Controller {
public function __construct()
{
$this->middleware('auth');
}
public function get($file)
{
return Storage::disk('private')->get($file);
}
}

Related

Laravel deployed to shared hosting not displaying image

I deployed a laravel app to shared hosting (hostinger). Everything is working fine except the images which are not showing up.
I have created a symlink of my storage folder with my public_html folder. Files uploaded enters the public folder but when I link the images they still do not show up.
I have created a symlink to the public_html since I cannot access the public folder. I need help on this please
I need the image to be displayed on the browser
In default Laravel deployment the symlink is created in public folder as storage and links to ../storage/app/public.
In order to debug your problem, please have a look at the developer tools of your browser to find out whether it is a 404 or 403 problem (or even another).
Please check for correct permissions. Otherwise you may change the physical storage path to something inside the public folder. This avoids the requirement to create a symlink. Keep in mind to protect non-public storage via .htaccess for example.
You have to the path to your public assets directory if it is not public directory in the root folder. In your case, the public assets directory is public_html. So please bind the path to it from the root folder.
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
if (App::environment('prod')) {
$this->app->bind('path.public', function() {
return base_path('../../public_html');
});
}
}
}
had the same problem, remember to run 'php artisan config:cache' as per Laravel Deployment guidelines.
Running the command creates a general configuration file
in app/bootstrap/cache/config.php with all settings including directories and links that you should update

Laravel image cache using Dropbox as disk

I'm using this package (https://github.com/spatie/flysystem-dropbox) to storage and get images from Dropbox.
This works fine but images have to load everytime the page is refreshed. I wonder if you know any image cache solution that works in this case and if can please provide with a minimal working example.
Thanks.
One way to solve this would be to create your own caching system. If the image doesn't exist on your local file system, pull it from Dropbox and then save it to the local file system and serve it. If it already exists in the local file system just serve it from the local file system.
1 Route
Serve the images from their own route.
Route::get('images/{filename}', [
'uses' => 'ImageController#getImage'
]);
2 Controller
Check the local file system to see if the file already exists, otherwise pull it from dropbox and store it in the local file system.
<?php
namespace App\Http\Controllers;
class ImageController extends Controller
public function __construct()
{
parent::__construct();
}
public function getImage($filename)
{
// If the file doesn't exist
if(!file_exists('/path/to/' . $filename)) {
// 1. Get the image from dropbox
// 2. Save the image to local storage
}
// 3. Serve the image from local storage
}
}

Laravel Route to Standalone WebApp

I am trying to build a portal in Laravel to serve some other, standalone web apps (not built in Laravel), but I am struggling to find out how to route to these apps if I want to place them outside the public folder.
In the past, I would use (temporary) symlinks for this kind of things, but I was wondering if Laravel provides another solution.
So, I have a folder:
module
module/index.php
module/js/whatever
module/css/whatever
module/img/whatever
and I want a route /modules/1 to link to index.php in the module-folder in such a way that the resources in this folder (js/css/img) are also accessible.
Any suggestions?
You can include other PHP files with require_once.
web.php
Route::any('/webapp/{assets?}', 'WebAppController#index');
WebAppController
class WebAppController {
public function index(Request $request) {
require_once '../module/index.php';
if ($request->assets) {
// check from session if user is logged in
// require asset as well
// (or download them https://laravel.com/docs/5.5/responses#file-downloads)
}
}
}
http://php.net/manual/en/function.require-once.php

crudbooster, How to change storage path in laravel to public?

I use crudbooster admin generator in laravel 5.4, if I upload a file from a form, it will be stored in own storage directory. Then I should create a symlink to that storage path in public path.
I can't use creating symlinks on my system because of the limitation. How can I upload files directly to public/uploads instead of storage/app/uploads?
I honestly have no clue. Best I can do is point you in the right direction. Crudbooster depends on a package called UniShard/laravel-filemanager. I was looking through the config file for this package and it is similar to the lfm.php in your config folder except there are more options. Perhaps you could use one of these additional options such as base_directory. Not sure how this will work out and it could just be poorly coded.
Original Answer:
You need to create a new disk.
In config\filesystems.php, add this.
'disks' => [
'uploads' => [
'driver' => 'local',
'root' => public_path() . '/uploads'
],
],
Now, when you want to use the storage facade you can just do this:
Storage::disk('uploads');
An example usage:
Storage::disk('uploads')->put('filename', $file_content);
Hope this helps.
we can change it in
vendor/crocodicstudio/crudbooster/src/controllers/cbcontroller.php line: 1010

Why can't my class be found, when it's in the same namespace?

I have created a modules folder in my Laravel app. There are two modules so far, but I'm just concentrating on core here.
I'm using Confide and Entrust to build User functionality, like so:
namespace App\Modules\Core;
use Zizaco\Confide\ConfideUser;
use Zizaco\Entrust\HasRole;
class User extends ConfideUser {
use HasRole;
}
and Permissions:
namespace App\Modules\Core;
use Zizaco\Entrust\EntrustPermission;
class Permission extends EntrustPermission
{
}
and Roles:
namespace App\Modules\Core;
use Zizaco\Entrust\EntrustRole;
class Role extends EntrustRole
{
}
My Composer.json autoload reads:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/modules"
],
"psr-0": {
"App\\Modules\\": "modules/"
}
},
I put the psr-0 stuff in there because I couldn't get things to work. They still don't work, though the output autoload files when I run composer seem to have promising entries in them.
The database has been migrated, and now I'm trying to run the database seeding. My seeding script reads:
use App\Modules\Core\User;
use App\Modules\Core\Role;
use App\Modules\Core\Permission;
class UserTablesSeeder extends Seeder {
public function run()
{
DB::table('users')->insert(array(
'email' => 'xxx',
'first_name' => 'xxx',
'password' => 'xxxx',
'active' => 1
));
$admin = new Role;
$admin->name = 'Admin';
$admin->save();
$manageUsers = new Permission;
$manageUsers->name = 'manage_standard_users';
$manageUsers->display_name = 'Manage Users';
$manageUsers->save();
$admin->perms()->sync(array($manageUsers->id));
$user = User::where('email','=','xxx')->first();
$user->attachRole($admin);
}
}
But when I run php artisan db:seed I get an error:
PHP Fatal error: Class 'Permission' not found in /home/wedding/quincy/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php on line 604
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Class 'Permission' not found","file":"\/home\/wedding\/quincy\/vendor\/laravel\/framework\/src\/Illuminate\/Database\/Eloquent\/Model.php","line":604}}
If I get rid of all the namespacing it all works just fine, but I think I should keep the namespaces because of the modularity I'm trying to create.
I've run composer dump-autoload, and install for when I added the psr-0 entry. So I'm not sure what else I need to do. I'm very new to composer, so at this point I'm lost as to what the problem is.
Thanks in advance.
Don't know if you found your answer.
I think you need to update your role and permission namespaced class names here:
File: vendor/entrust/config/config.php:
(Default is just "Role" and "Permission" without a namespace, so it doesn't work when you move your implementations into one).
You also have two other options:
add an alias for the fully namedspaced permission and role class on the app/config.php (Role => "Namespace").
there's a mechanism to override package config settings with appropriately named files. You can override just the two entries you need (the Role and Permission namespaces).
Confide and Entrust both are looking for Role and Permission model in global namespace. As you have changed namespace of both these models, Confide and Entrust are not able to find it. To solve this problem, you need to override Entrust configuration.
Create directory "app/config/packages/zizaco/entrust"
Copy file "vendor/zizaco/entrust/src/config/config.php" to "app/config/packages/zizaco/entrust/config.php"
Edit "app/config/packages/zizaco/entrust/config.php" and change following two lines
'role' => 'App\Modules\Core\Role',
'permission' => 'App\Modules\Core\Permission',
php artisan clear-compiled
php artisan optimize
You should rely on Laravel's packages (created thru Workbench, for instance) while developing localy.
Packages are the primary way of adding functionality to Laravel.
Workbench packages and their classes are handled automaticaly by Laravel - no need to configure anything.
More informations here: http://laravel.com/docs/packages
if you want to use your own modules instead of standard workbench packages, check out this article that depics how to achieve that:
http://creolab.hr/2013/05/modules-in-laravel-4/
summary by the author ( Boris Strahija ):
Laravel 4 is heavily based on composer packages, which is a good thing, but sometimes developers (like myself) like to separate their code into modules. This is especially nice when building larger projects. Now this was fairly easy to do in Laravel 3 with the bundles system, but in Laravel 4 many people just recommend building packages since L4 has a nice workbench feature. This is all good, but sometimes I like to separate my app specific controllers and views into modules, and not have to go through it with the workbench.
In short, you have to
put your modules code somwhere (for example /app/modules/)
include the directory in composer.json file, under autoload/classmap
create an appropriate service providers (Laravel 4 uses service providers to register and boot up the packages, you can use it with modules as well)
register the service providers - add them to app config in “app/config/app.php” under the providers array
So now we have out modules fully working. You can add module specific routes, group your controllers/views/models, get module configuration like this:
Config::get('content::channels');
Or get translated phrases like this:
Lang::get('shop::errors.no_items_in_cart');
Finally, to test your modules you can create some routes, but that is up to you how you use your code.
If you look at Doctrine composer.json, for example /vendor/doctrine/cache/composer.json:
"autoload": {
"psr-0": { "Doctrine\\Common\\Cache\\": "lib/" }
},
The files are located in:
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/ArrayCache.php
/vendor/doctrine/cache/lib/Doctrine/Common/Cache/Cache.php
... and so on
By that logic, I think you should put your files in:
modules/App/Modules/Core/User.php
modules/App/Modules/Core/Permission.php
modules/App/Modules/Core/Role.php
From you screenshot the Permission class is located in the models folder so when you include your namespace you should type
use App\Modules\Core\Models\Permission;

Resources