diff --git a/src/App/Limitations/LimitationManager.php b/src/App/Limitations/LimitationManager.php deleted file mode 100644 index 732f7e44..00000000 --- a/src/App/Limitations/LimitationManager.php +++ /dev/null @@ -1,30 +0,0 @@ -driver() ->$method($this, ...$parameters); } diff --git a/src/Domain/Files/Controllers/FileAccess/GetFileController.php b/src/Domain/Files/Controllers/FileAccess/GetFileController.php index 977172b0..019b9a85 100644 --- a/src/Domain/Files/Controllers/FileAccess/GetFileController.php +++ b/src/Domain/Files/Controllers/FileAccess/GetFileController.php @@ -2,6 +2,7 @@ namespace Domain\Files\Controllers\FileAccess; use Gate; +use Illuminate\Http\Response; use App\Http\Controllers\Controller; use Domain\Files\Models\File as UserFile; use Domain\Files\Actions\DownloadFileAction; @@ -18,11 +19,19 @@ class GetFileController extends Controller public function __invoke( string $filename, - ): BinaryFileResponse { + ): Response|BinaryFileResponse { $file = UserFile::withTrashed() ->where('basename', $filename) ->firstOrFail(); + // Check if user can download file + if (! $file->owner->canDownload()) { + return response([ + 'type' => 'error', + 'message' => 'This user action is not allowed.', + ], 401); + } + if (! Gate::any(['can-edit', 'can-view'], [$file, null])) { abort(403, 'Access Denied'); } diff --git a/src/Domain/Files/Controllers/FileAccess/VisitorGetFileController.php b/src/Domain/Files/Controllers/FileAccess/VisitorGetFileController.php index ce143b3c..f236d817 100644 --- a/src/Domain/Files/Controllers/FileAccess/VisitorGetFileController.php +++ b/src/Domain/Files/Controllers/FileAccess/VisitorGetFileController.php @@ -2,6 +2,7 @@ namespace Domain\Files\Controllers\FileAccess; use Domain\Files\Models\File; +use Illuminate\Http\Response; use Domain\Sharing\Models\Share; use App\Http\Controllers\Controller; use Domain\Files\Actions\DownloadFileAction; @@ -26,7 +27,15 @@ class VisitorGetFileController extends Controller public function __invoke( $filename, Share $shared, - ): BinaryFileResponse { + ): BinaryFileResponse|Response { + // Check if user can download file + if (! $shared->user->canDownload()) { + return response([ + 'type' => 'error', + 'message' => 'This user action is not allowed.', + ], 401); + } + // Check ability to access protected share files ($this->protectShareRecord)($shared); diff --git a/src/Support/helpers.php b/src/Support/helpers.php index 0e3635a7..098fd002 100644 --- a/src/Support/helpers.php +++ b/src/Support/helpers.php @@ -33,11 +33,11 @@ if (! function_exists('obfuscate_email')) { } } -if (! function_exists('get_limitation_driver')) { +if (! function_exists('get_restriction_driver')) { /** * Get driver for limitation API */ - function get_limitation_driver(): string + function get_restriction_driver(): string { return match (get_settings('subscription_type')) { 'fixed' => 'fixed', diff --git a/tests/App/Limitations/MeteredBillingLimitationTest.php b/tests/App/Limitations/MeteredBillingLimitationTest.php deleted file mode 100644 index 3d1d1052..00000000 --- a/tests/App/Limitations/MeteredBillingLimitationTest.php +++ /dev/null @@ -1,112 +0,0 @@ -insert([ - 'name' => 'subscription_type', - 'value' => 'metered', - ]); - } - - /** - * @test - */ - public function it_can_upload() - { - $user = User::factory() - ->hasFailedpayments(2) - ->create(); - - $this->assertEquals(true, $user->canUpload()); - } - - /** - * @test - */ - public function it_cant_upload_because_user_has_3_failed_payments() - { - $user = User::factory() - ->hasFailedpayments(3) - ->create(); - - $this->assertEquals(false, $user->canUpload()); - } - - /** - * @test - */ - public function it_can_create_new_folder() - { - $user = User::factory() - ->create(); - - // Create basic folder - $this - ->actingAs($user) - ->postJson('/api/create-folder', [ - 'name' => 'New Folder', - ]) - ->assertStatus(201); - - // Create team folder - $this - ->actingAs($user) - ->postJson('/api/teams/folders', [ - 'name' => 'New Team Folder', - 'invitations' => [ - [ - 'email' => 'john@doe.com', - 'permission' => 'can-edit', - 'type' => 'invitation', - ], - ], - ]) - ->assertStatus(201); - - $this->assertDatabaseCount('folders', 2); - } - - /** - * @test - */ - public function it_cant_create_new_folder_because_user_has_3_failed_payments() - { - $user = User::factory() - ->hasFailedpayments(3) - ->create(); - - // Create basic folder - $this - ->actingAs($user) - ->postJson('/api/create-folder', [ - 'name' => 'New Folder', - ]) - ->assertStatus(401); - - // Create team folder - $this - ->actingAs($user) - ->postJson('/api/teams/folders', [ - 'name' => 'New Folder', - 'invitations' => [ - [ - 'email' => 'john@doe.com', - 'permission' => 'can-edit', - 'type' => 'invitation', - ], - ], - ]) - ->assertStatus(401); - - $this->assertDatabaseCount('folders', 0); - } -} diff --git a/tests/App/Limitations/DefaultLimitationTest.php b/tests/App/Restrictions/DefaultRestrictionsTest.php similarity index 75% rename from tests/App/Limitations/DefaultLimitationTest.php rename to tests/App/Restrictions/DefaultRestrictionsTest.php index ae4946b1..3378a612 100644 --- a/tests/App/Limitations/DefaultLimitationTest.php +++ b/tests/App/Restrictions/DefaultRestrictionsTest.php @@ -1,13 +1,14 @@ create() ->each( fn ($member) => TeamFolderMember::factory() - ->create([ - 'parent_id' => $user->folders[0]->id, - 'user_id' => $member->id, - ]) + ->create([ + 'parent_id' => $user->folders[0]->id, + 'user_id' => $member->id, + ]) ); // Try invite new members, it has to fail @@ -184,4 +185,54 @@ class DefaultLimitationTest extends TestCase ]) ->assertCreated(); } + + /** + * @test + */ + public function it_can_get_private_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->actingAs($user) + ->get("file/$file->name") + ->assertStatus(404); + } + + /** + * @test + */ + public function it_can_get_shared_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + $share = Share::factory() + ->create([ + 'item_id' => $file->id, + 'user_id' => $user->id, + 'type' => 'file', + 'is_protected' => false, + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->get("file/$file->name/$share->token") + ->assertStatus(404); + } } diff --git a/tests/App/Limitations/FixedBillingLimitationTest.php b/tests/App/Restrictions/FixedBillingRestrictionsTest.php similarity index 70% rename from tests/App/Limitations/FixedBillingLimitationTest.php rename to tests/App/Restrictions/FixedBillingRestrictionsTest.php index ee1b7022..348adefe 100644 --- a/tests/App/Limitations/FixedBillingLimitationTest.php +++ b/tests/App/Restrictions/FixedBillingRestrictionsTest.php @@ -1,13 +1,14 @@ create() ->each( fn ($member) => TeamFolderMember::factory() - ->create([ - 'parent_id' => $user->folders[0]->id, - 'user_id' => $member->id, - ]) + ->create([ + 'parent_id' => $user->folders[0]->id, + 'user_id' => $member->id, + ]) ); // Try invite new members, it has to fail @@ -145,4 +146,54 @@ class FixedBillingLimitationTest extends TestCase ]) ->assertCreated(); } + + /** + * @test + */ + public function it_can_get_private_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->actingAs($user) + ->get("file/$file->name") + ->assertStatus(404); + } + + /** + * @test + */ + public function it_can_get_shared_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + $share = Share::factory() + ->create([ + 'item_id' => $file->id, + 'user_id' => $user->id, + 'type' => 'file', + 'is_protected' => false, + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->get("file/$file->name/$share->token") + ->assertStatus(404); + } } diff --git a/tests/App/Restrictions/MeteredBillingRestrictionsTest.php b/tests/App/Restrictions/MeteredBillingRestrictionsTest.php new file mode 100644 index 00000000..caf65836 --- /dev/null +++ b/tests/App/Restrictions/MeteredBillingRestrictionsTest.php @@ -0,0 +1,216 @@ +insert([ + 'name' => 'subscription_type', + 'value' => 'metered', + ]); + } + + /** + * @test + */ + public function it_can_upload() + { + $user = User::factory() + ->hasFailedpayments(2) + ->create(); + + $this->assertEquals(true, $user->canUpload()); + } + + /** + * @test + */ + public function it_cant_upload_because_user_has_3_failed_payments() + { + $user = User::factory() + ->hasFailedpayments(3) + ->create(); + + $this->assertEquals(false, $user->canUpload()); + } + + /** + * @test + */ + public function it_can_create_new_folder() + { + $user = User::factory() + ->create(); + + // Create basic folder + $this + ->actingAs($user) + ->postJson('/api/create-folder', [ + 'name' => 'New Folder', + ]) + ->assertStatus(201); + + // Create team folder + $this + ->actingAs($user) + ->postJson('/api/teams/folders', [ + 'name' => 'New Team Folder', + 'invitations' => [ + [ + 'email' => 'john@doe.com', + 'permission' => 'can-edit', + 'type' => 'invitation', + ], + ], + ]) + ->assertStatus(201); + + $this->assertDatabaseCount('folders', 2); + } + + /** + * @test + */ + public function it_cant_create_new_folder_because_user_has_3_failed_payments() + { + $user = User::factory() + ->hasFailedpayments(3) + ->create(); + + // Create basic folder + $this + ->actingAs($user) + ->postJson('/api/create-folder', [ + 'name' => 'New Folder', + ]) + ->assertStatus(401); + + // Create team folder + $this + ->actingAs($user) + ->postJson('/api/teams/folders', [ + 'name' => 'New Folder', + 'invitations' => [ + [ + 'email' => 'john@doe.com', + 'permission' => 'can-edit', + 'type' => 'invitation', + ], + ], + ]) + ->assertStatus(401); + + $this->assertDatabaseCount('folders', 0); + } + + /** + * @test + */ + public function it_cant_get_private_file_because_user_has_3_failed_payments() + { + $user = User::factory() + ->hasFailedpayments(3) + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + $this + ->actingAs($user) + ->get("file/$file->name") + ->assertStatus(401); + } + + /** + * @test + */ + public function it_can_get_private_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->actingAs($user) + ->get("file/$file->name") + ->assertStatus(404); + } + + /** + * @test + */ + public function it_cant_get_shared_file_because_user_has_3_failed_payments() + { + $user = User::factory() + ->hasFailedpayments(3) + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + $share = Share::factory() + ->create([ + 'item_id' => $file->id, + 'user_id' => $user->id, + 'type' => 'file', + 'is_protected' => false, + ]); + + $this + ->get("file/$file->name/$share->token") + ->assertStatus(401); + } + + /** + * @test + */ + public function it_can_get_shared_file() + { + $user = User::factory() + ->create(); + + $file = File::factory() + ->create([ + 'user_id' => $user->id, + 'basename' => 'fake-file.pdf', + 'name' => 'fake-file.pdf', + ]); + + $share = Share::factory() + ->create([ + 'item_id' => $file->id, + 'user_id' => $user->id, + 'type' => 'file', + 'is_protected' => false, + ]); + + // 404 but, ok, because there is not stored temporary file in test + $this + ->get("file/$file->name/$share->token") + ->assertStatus(404); + } +} diff --git a/tests/App/Limitations/LimitationTest.php b/tests/App/Restrictions/RestrictionsTest.php similarity index 72% rename from tests/App/Limitations/LimitationTest.php rename to tests/App/Restrictions/RestrictionsTest.php index d80753b0..1c7254df 100644 --- a/tests/App/Limitations/LimitationTest.php +++ b/tests/App/Restrictions/RestrictionsTest.php @@ -1,10 +1,10 @@ 'metered', ]); - $this->assertEquals('metered', get_limitation_driver()); + $this->assertEquals('metered', get_restriction_driver()); } /** * @test @@ -30,7 +30,7 @@ class LimitationTest extends TestCase 'value' => 'fixed', ]); - $this->assertEquals('fixed', get_limitation_driver()); + $this->assertEquals('fixed', get_restriction_driver()); } /** * @test @@ -42,6 +42,6 @@ class LimitationTest extends TestCase $subscriptionType?->delete(); - $this->assertEquals('default', get_limitation_driver()); + $this->assertEquals('default', get_restriction_driver()); } }