editing with shared items in public

This commit is contained in:
carodej
2020-04-28 18:06:38 +02:00
parent eb6bd646c8
commit 2614efe601
77 changed files with 1171 additions and 578 deletions

View File

@@ -131,7 +131,7 @@ class BrowseController extends Controller
*
* @return array
*/
public function folder_tree() {
public function navigation_tree() {
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', 0)

View File

@@ -2,387 +2,327 @@
namespace App\Http\Controllers\FileFunctions;
use App\Share;
use Illuminate\Support\Arr;
use App\Http\Requests\FileFunctions\CreateFolderRequest;
use App\Http\Requests\FileFunctions\DeleteItemRequest;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\Http\Requests\FileFunctions\MoveItemRequest;
use App\Http\Requests\FileFunctions\UploadRequest;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Intervention\Image\ImageManagerStatic as Image;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Storage;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Http\Tools\Guardian;
use App\Http\Tools\Editor;
use App\FileManagerFolder;
use App\FileManagerFile;
use Response;
use Exception;
class EditItemsController extends Controller
{
/**
* Create new folder
* Create new folder for authenticated master|editor user
*
* @param Request $request
* @return array
* @param CreateFolderRequest $request
* @return FileManagerFolder|Model
*/
public function create_folder(Request $request)
public function user_create_folder(CreateFolderRequest $request)
{
// Check permission to create folder for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $request->parent_id);
// Check permission to create folder for authenticated editor
if ($request->user()->tokenCan('editor')) {
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
}
// Validate request
$validator = Validator::make($request->all(), [
'parent_id' => 'required|integer',
'name' => 'string',
]);
// Create new folder
return Editor::create_folder($request);
}
// Return error
if ($validator->fails()) abort(400, 'Bad input');
/**
* Create new folder for guest user with edit permission
*
* @param CreateFolderRequest $request
* @param $token
* @return FileManagerFolder|Model
*/
public function guest_create_folder(CreateFolderRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
// Get parent_id from request
$parent_id = $request->parent_id === 0 ? 0 : $request->parent_id;
// Check shared permission
if (!is_editor($shared)) abort(403);
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
// Create folder
$folder = FileManagerFolder::create([
'user_id' => Auth::id(),
'parent_id' => $parent_id,
'name' => $request->has('name') ? $request->input('name') : 'New Folder',
'type' => 'folder',
'unique_id' => $this->get_unique_id(),
'user_scope' => $request->user()->token()->scopes[0],
]);
// Return new folder
return $folder;
return Editor::create_folder($request, $shared);
}
/**
* Rename item name
* Rename item for authenticated master|editor user
*
* @param Request $request
* @param RenameItemRequest $request
* @param $unique_id
* @return mixed
*/
public function rename_item(Request $request, $unique_id)
public function user_rename_item(RenameItemRequest $request, $unique_id)
{
// Validate request
$validator = Validator::make($request->all(), [
'name' => 'required|string',
'type' => 'required|string',
]);
// Check permission to rename item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get user id
$user_id = Auth::id();
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Update folder name
if ($request->type === 'folder') {
// Get file|folder item
$item = get_item($request->type, $unique_id, Auth::id());
$item = FileManagerFolder::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
// Check permission to rename for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $item->unique_id);
// Check access to requested directory
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
$item->name = $request->name;
$item->save();
} else {
$item = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
// Check permission to rename for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $item->folder_id);
}
$item->name = $request->name;
$item->save();
}
// Return updated item
return $item;
// Rename Item
return Editor::rename_item($request, $unique_id);
}
/**
* Delete item
* Rename item for guest user with edit permission
*
* @param Request $request
* @param RenameItemRequest $request
* @param $unique_id
* @throws \Exception
* @param $token
* @return mixed
*/
public function delete_item(Request $request, $unique_id)
public function guest_rename_item(RenameItemRequest $request, $unique_id, $token)
{
// Validate request
$validator = Validator::make($request->all(), [
'type' => 'required|string',
'force_delete' => 'required|boolean',
]);
// Get shared record
$shared = get_shared($token);
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get user id
$user = Auth::user();
// Get file|folder item
$item = get_item($request->type, $unique_id, $shared->user_id);
// Delete folder
// Check access to requested item
if ($request->type === 'folder') {
// Get folder
$folder = FileManagerFolder::withTrashed()
->with(['folders'])
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// Check permission to delete for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $folder->unique_id);
}
// Force delete children files
if ($request->force_delete) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
// Get children files
$files = FileManagerFile::onlyTrashed()
->where('user_id', $user->id)
->whereIn('folder_id', Arr::flatten([$unique_id, $child_folders]))
->get();
// Remove all children files
foreach ($files as $file) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if (!is_null($file->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Delete folder record
$folder->forceDelete();
} else {
// Remove folder from user favourites
$user->favourites()->detach($unique_id);
// Soft delete folder record
$folder->delete();
}
Guardian::check_item_access($item->unique_id, $shared);
} else {
$file = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// Check permission to delete for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $file->folder_id);
}
if ($request->force_delete) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
} else {
// Soft delete file
$file->delete();
}
Guardian::check_item_access($item->folder_id, $shared);
}
// Rename item
return Editor::rename_item($request, $unique_id, $shared);
}
/**
* Upload items
* Delete item for authenticated master|editor user
*
* @param Request $request
* @return array
* @param DeleteItemRequest $request
* @param $unique_id
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function upload_item(Request $request)
public function user_delete_item(DeleteItemRequest $request, $unique_id)
{
// Check permission to upload for authenticated public editor
if ( ! $request->user()->tokenCan('master') ) {
$this->check_access($request, $request->parent_id);
// Check permission to delete item for authenticated editor
if ($request->user()->tokenCan('editor')) {
// Prevent force delete for non-master users
if ($request->force_delete) abort('401');
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// Get file|folder item
$item = get_item($request->type, $unique_id, Auth::id());
// Check access to requested directory
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
}
// Delete item
Editor::delete_item($request, $unique_id);
// Return response
return response(null, 204);
}
/**
* Delete item for guest user with edit permission
*
* @param DeleteItemRequest $request
* @param $unique_id
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
* @throws Exception
*/
public function guest_delete_item(DeleteItemRequest $request, $unique_id, $token)
{
// Get shared record
$shared = get_shared($token);
// Check shared permission
if (!is_editor($shared)) abort(403);
// Get file|folder item
$item = get_item($request->type, $unique_id, $shared->user_id);
// Check access to requested item
if ($request->type === 'folder') {
Guardian::check_item_access($item->unique_id, $shared);
} else {
Guardian::check_item_access($item->folder_id, $shared);
}
// Delete item
Editor::delete_item($request, $unique_id, $shared);
// Return response
return response(null, 204);
}
/**
* Delete file for authenticated master|editor user
*
* @param UploadRequest $request
* @return FileManagerFile|Model
*/
public function user_upload(UploadRequest $request)
{
// Check if user can upload
if (config('vuefilemanager.limit_storage_by_capacity') && user_storage_percentage() >= 100) {
abort(423, 'You exceed your storage limit!');
}
// Validate request
$validator = Validator::make($request->all(), [
'parent_id' => 'required|integer',
'file' => 'required|file',
]);
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
// File
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$filetype = get_file_type($file);
$thumbnail = null;
$filesize = $file->getSize();
$directory = 'file-manager';
// create directory if not exist
if (!Storage::disk('local')->exists($directory)) {
Storage::disk('local')->makeDirectory($directory);
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
}
// Store to disk
Storage::disk('local')->putFileAs($directory, $file, $filename, 'public');
// Return new uploaded file
return Editor::upload($request);
}
// Create image thumbnail
if ($filetype == 'image') {
/**
* Delete file for guest user with edit permission
*
* @param UploadRequest $request
* @param $token
* @return FileManagerFile|Model
*/
public function guest_upload(UploadRequest $request, $token)
{
// Get shared record
$shared = get_shared($token);
$thumbnail = 'thumbnail-' . $filename;
// Check shared permission
if (!is_editor($shared)) abort(403);
// Create intervention image
$image = Image::make($file->getRealPath())->orientate();
// Check access to requested directory
Guardian::check_item_access($request->parent_id, $shared);
$image->resize(256, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Return new uploaded file
$new_file = Editor::upload($request, $shared);
// Store thumbnail to s3
Storage::disk('local')->put($directory . '/' . $thumbnail, $image);
}
// Store file
$new_file = FileManagerFile::create([
'user_id' => Auth::id(),
'name' => pathinfo($file->getClientOriginalName())['filename'],
'basename' => $filename,
'folder_id' => $folder_id,
'mimetype' => $file->getClientOriginalExtension(),
'filesize' => $filesize,
'type' => $filetype,
'thumbnail' => $thumbnail,
'unique_id' => $this->get_unique_id(),
'user_scope' => $request->user()->token()->scopes[0],
]);
// Set public access url
$new_file->setPublicUrl($token);
return $new_file;
}
/**
* Move item
* Move item for authenticated master|editor user
*
* @param Request $request
* @param MoveItemRequest $request
* @param $unique_id
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
* @return ResponseFactory|\Illuminate\Http\Response
*/
public function move_item(Request $request, $unique_id)
public function user_move(MoveItemRequest $request, $unique_id)
{
// Validate request
$validator = Validator::make($request->all(), [
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
]);
// Check permission to upload for authenticated editor
if ($request->user()->tokenCan('editor')) {
// Return error
if ($validator->fails()) abort(400, 'Bad input');
// check if shared_token cookie exist
if (!$request->hasCookie('shared_token')) abort('401');
// Get user id
$user_id = Auth::id();
// Get shared token
$shared = get_shared($request->cookie('shared_token'));
if ($request->from_type === 'folder') {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->parent_id = $request->to_unique_id;
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->folder_id = $request->to_unique_id;
// Check access to requested directory
Guardian::check_item_access($request->to_unique_id, $shared);
}
$item->update();
// Move item
Editor::move($request, $unique_id);
return response('Done!', 204);
}
/**
* Get unique id
* Move item for guest user with edit permission
*
* @return int
* @param MoveItemRequest $request
* @param $unique_id
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
*/
private function get_unique_id(): int
public function guest_move(MoveItemRequest $request, $unique_id, $token)
{
// Get files and folders
$folders = FileManagerFolder::withTrashed()->get();
$files = FileManagerFile::withTrashed()->get();
// Get shared record
$shared = get_shared($token);
// Get last ids
$folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id;
$files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id;
// Check shared permission
if (!is_editor($shared)) abort(403);
// Count new unique id
$unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1;
$moving_unique_id = $unique_id;
return $unique_id;
}
if ($request->from_type !== 'folder') {
$file = FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $shared->user_id)
->firstOrFail();
/**
* Check if user has access to requested folder
*
* @param $request
*/
protected function check_access($request, $parent_id): void
{
// check if shared_token cookie exist
if (! $request->hasCookie('shared_token')) abort('401');
$moving_unique_id = $file->folder_id;
}
// Get shared token
$shared = Share::where(DB::raw('BINARY `token`'), $request->cookie('shared_token'))
->firstOrFail();
// Check access to requested item
Guardian::check_item_access([
$request->to_unique_id, $moving_unique_id
], $shared);
// Get all children folders
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Move item
Editor::move($request, $unique_id, $shared);
// Get all authorized parent folders by shared folder as root of tree
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Check user access
if (!in_array($parent_id, $accessible_folder_ids)) abort(403);
return response('Done!', 204);
}
}

View File

@@ -89,6 +89,7 @@ class ShareController extends Controller
*
* @param $token
* @return ResponseFactory|\Illuminate\Http\Response
* @throws \Exception
*/
public function destroy($token)
{

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Sharing;
use App\Http\Controllers\Controller;
use App\Http\Requests\Share\AuthenticateShareRequest;
use App\Http\Resources\ShareResource;
use App\Http\Tools\Guardian;
use Illuminate\Contracts\View\Factory;
use Illuminate\Support\Facades\Cookie;
use Illuminate\Support\Facades\DB;
@@ -91,7 +92,7 @@ class FileSharingController extends Controller
$shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail();
// Check if user can get directory
$this->check_folder_access($unique_id, $shared);
Guardian::check_item_access($unique_id, $shared);
// Get files and folders
list($folders, $files) = $this->get_items($unique_id, $shared);
@@ -117,7 +118,7 @@ class FileSharingController extends Controller
}
// Check if user can get directory
$this->check_folder_access($unique_id, $shared);
Guardian::check_item_access($unique_id, $shared);
// Get files and folders
list($folders, $files) = $this->get_items($unique_id, $shared);
@@ -177,24 +178,64 @@ class FileSharingController extends Controller
}
/**
* Check if user has access to requested folder
* Get navigation tree
*
* @param $folder_unique_id
* @param $shared
* @param Request $request
* @return array
*/
protected function check_folder_access($unique_id, $shared): void
public function get_private_navigation_tree(Request $request)
{
// Get all children folders
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
// Get sharing record
$shared = Share::where('token', $request->cookie('shared_token'))->firstOrFail();
// Check if user can get directory
Guardian::check_item_access($shared->item_id, $shared);
// Get folders
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->get();
->where('user_id', $shared->user_id)
->get(['id', 'parent_id', 'unique_id', 'name']);
// Get all authorized parent folders by shared folder as root of tree
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Return folder tree
return [
[
'unique_id' => $shared->item_id,
'name' => __('vuefilemanager.home'),
'location' => 'public',
'folders' => $folders,
]
];
}
// Check user access
if (!in_array($unique_id, $accessible_folder_ids)) abort(401);
/**
* Get navigation tree
*
* @return array
*/
public function get_public_navigation_tree($token)
{
// Get sharing record
$shared = Share::where('token', $token)->firstOrFail();
// Check if user can get directory
Guardian::check_item_access($shared->item_id, $shared);
// Get folders
$folders = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('parent_id', $shared->item_id)
->where('user_id', $shared->user_id)
->get(['id', 'parent_id', 'unique_id', 'name']);
// Return folder tree
return [
[
'unique_id' => $shared->item_id,
'name' => __('vuefilemanager.home'),
'location' => 'public',
'folders' => $folders,
]
];
}
/**

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class CreateFolderRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'parent_id' => 'required|integer',
'name' => 'string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class DeleteItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'type' => 'required|string',
'force_delete' => 'required|boolean',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class MoveItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'to_unique_id' => 'required|integer',
'from_type' => 'required|string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class RenameItemRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string',
'type' => 'required|string',
];
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace App\Http\Requests\FileFunctions;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
class UploadRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'parent_id' => 'required|integer',
'file' => 'required|file',
];
}
}

272
app/Http/Tools/Editor.php Normal file
View File

@@ -0,0 +1,272 @@
<?php
namespace App\Http\Tools;
use App;
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Http\Requests\FileFunctions\RenameItemRequest;
use App\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
class Editor
{
/**
* Create new directory
*
* @param $request
* @param null $shared
* @return FileManagerFolder|\Illuminate\Database\Eloquent\Model
*/
public static function create_folder($request, $shared = null)
{
// Get variables
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$name = $request->has('name') ? $request->input('name') : 'New Folder';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Create folder
$folder = FileManagerFolder::create([
'parent_id' => $request->parent_id,
'unique_id' => get_unique_id(),
'user_scope' => $user_scope,
'user_id' => $user_id,
'type' => 'folder',
'name' => $name,
]);
// Return new folder
return $folder;
}
/**
* Rename item name
*
* @param RenameItemRequest $request
* @param $unique_id
* @return mixed
*/
public static function rename_item($request, $unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get item
$item = get_item($request->type, $unique_id, $user_id);
// Rename item
$item->update([
'name' => $request->name
]);
// Return updated item
return $item;
}
/**
* Delete file or folder
*
* @param $request
* @param $unique_id
* @param null $shared
* @throws \Exception
*/
public static function delete_item($request, $unique_id, $shared = null)
{
// Get user id
$user = is_null($shared) ? Auth::user() : User::findOrFail($shared->user_id);
// Delete folder
if ($request->type === 'folder') {
// Get folder
$folder = FileManagerFolder::withTrashed()
->with(['folders'])
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// TODO: delete folder shared record
// Force delete children files
if ($request->force_delete) {
// Get children folder ids
$child_folders = filter_folders_ids($folder->trashed_folders, 'unique_id');
// Get children files
$files = FileManagerFile::onlyTrashed()
->where('user_id', $user->id)
->whereIn('folder_id', Arr::flatten([$unique_id, $child_folders]))
->get();
// Remove all children files
foreach ($files as $file) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if (!is_null($file->thumbnail)) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Delete folder record
$folder->forceDelete();
}
// Soft delete items
if (!$request->force_delete) {
// Remove folder from user favourites
$user->favourites()->detach($unique_id);
// Soft delete folder record
$folder->delete();
}
}
// Delete item
if ($request->type !== 'folder') {
// Get file
$file = FileManagerFile::withTrashed()
->where('user_id', $user->id)
->where('unique_id', $unique_id)
->first();
// TODO: delete file shared record
// Force delete file
if ($request->force_delete) {
// Delete file
Storage::disk('local')->delete('/file-manager/' . $file->basename);
// Delete thumbnail if exist
if ($file->thumbnail) Storage::disk('local')->delete('/file-manager/' . $file->getOriginal('thumbnail'));
// Delete file permanently
$file->forceDelete();
}
// Soft delete file
if (!$request->force_delete) {
// Soft delete file
$file->delete();
}
}
}
/**
* Upload file
*
* @param $request
* @param $unique_id
* @param null $shared
* @return FileManagerFile|\Illuminate\Database\Eloquent\Model
*/
public static function upload($request, $shared = null)
{
// Get user data
$user_scope = is_null($shared) ? $request->user()->token()->scopes[0] : 'editor';
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
// Get parent_id from request
$folder_id = $request->parent_id === 0 ? 0 : $request->parent_id;
$file = $request->file('file');
// File
$filename = Str::random() . '-' . str_replace(' ', '', $file->getClientOriginalName());
$filetype = get_file_type($file);
$filesize = $file->getSize();
$directory = 'file-manager';
$thumbnail = null;
// create directory if not exist
if (!Storage::disk('local')->exists($directory)) {
Storage::disk('local')->makeDirectory($directory);
}
// Store to disk
Storage::disk('local')->putFileAs($directory, $file, $filename, 'public');
// Create image thumbnail
if ($filetype == 'image') {
// Get thumbnail name
$thumbnail = 'thumbnail-' . $filename;
// Create intervention image
$image = Image::make($file->getRealPath())->orientate();
// Resize image
$image->resize(256, null, function ($constraint) {
$constraint->aspectRatio();
})->stream();
// Store thumbnail to disk
Storage::disk('local')->put($directory . '/' . $thumbnail, $image);
}
// Store file
$options = [
'name' => pathinfo($file->getClientOriginalName())['filename'],
'mimetype' => $file->getClientOriginalExtension(),
'unique_id' => get_unique_id(),
'user_scope' => $user_scope,
'folder_id' => $folder_id,
'thumbnail' => $thumbnail,
'basename' => $filename,
'filesize' => $filesize,
'type' => $filetype,
'user_id' => $user_id,
];
// Return new file
return FileManagerFile::create($options);
}
/**
* Move folder or file to new location
*
* @param $request
* @param $unique_id
* @param null $shared
*/
public static function move($request, $unique_id, $shared = null)
{
// Get user id
$user_id = is_null($shared) ? Auth::id() : $shared->user_id;
if ($request->from_type === 'folder') {
// Move folder
$item = FileManagerFolder::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'parent_id' => $request->to_unique_id
]);
} else {
// Move file under new folder
$item = FileManagerFile::where('user_id', $user_id)
->where('unique_id', $unique_id)
->firstOrFail();
$item->update([
'folder_id' => $request->to_unique_id
]);
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Http\Tools;
use App;
use App\FileManagerFolder;
use Illuminate\Support\Arr;
class Guardian
{
/**
* Check access to requested directory
*
* @param integer|array $requested_id
* @param string $shared Shared record detail
*/
public static function check_item_access($requested_id, $shared)
{
// Get all children folders
$foldersIds = FileManagerFolder::with('folders:id,parent_id,unique_id,name')
->where('user_id', $shared->user_id)
->where('parent_id', $shared->item_id)
->get();
// Get all authorized parent folders by shared folder as root of tree
$accessible_folder_ids = Arr::flatten([filter_folders_ids($foldersIds), $shared->item_id]);
// Check user access
if ( is_array($requested_id) ) {
foreach ($requested_id as $id) {
if (!in_array($id, $accessible_folder_ids))
abort(403);
}
}
if (! is_array($requested_id)) {
if (! in_array($requested_id, $accessible_folder_ids))
abort(403);
}
}
}

View File

@@ -1,11 +1,83 @@
<?php
use App\FileManagerFile;
use App\FileManagerFolder;
use App\Share;
use ByteUnits\Metric;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic as Image;
/**
* Get folder or file item
*
* @param $type
* @param $unique_id
* @param $user_id
* @return \Illuminate\Database\Eloquent\Builder|Model
*/
function get_item($type, $unique_id, $user_id) {
if ($type === 'folder') {
// Return folder item
return FileManagerFolder::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
}
// Return file item
return FileManagerFile::where('unique_id', $unique_id)
->where('user_id', $user_id)
->firstOrFail();
}
/**
* Get shared token
*
* @param $token
* @return \Illuminate\Database\Eloquent\Builder|Model
*/
function get_shared($token) {
return Share::where(DB::raw('BINARY `token`'), $token)
->firstOrFail();
}
/**
* Check if shared permission is editor
*
* @param $shared
* @return bool
*/
function is_editor($shared) {
return $shared->permission === 'editor';
}
/**
* Get unique id
*
* @return int
*/
function get_unique_id(): int
{
// Get files and folders
$folders = FileManagerFolder::withTrashed()->get();
$files = FileManagerFile::withTrashed()->get();
// Get last ids
$folders_unique = $folders->isEmpty() ? 0 : $folders->last()->unique_id;
$files_unique = $files->isEmpty() ? 0 : $files->last()->unique_id;
// Count new unique id
$unique_id = $folders_unique > $files_unique ? $folders_unique + 1 : $files_unique + 1;
return $unique_id;
}
/**
* Store user avatar to storage
@@ -102,8 +174,7 @@ function get_storage_fill_percentage($used, $capacity)
*/
function user_storage_percentage()
{
$user = \Illuminate\Support\Facades\Auth::user();
$user = Auth::user();
return get_storage_fill_percentage($user->used_capacity, config('vuefilemanager.user_storage_capacity'));
}