|
2 | 2 |
|
3 | 3 | All notable changes to `laravel-media-secure` will be documented in this file. |
4 | 4 |
|
| 5 | +## Update dependencies and usage setup - 2025-07-24 |
| 6 | + |
| 7 | +**Full Changelog**: https://github.com/cleaniquecoders/laravel-media-secure/compare/2.2.1...3.0 |
| 8 | + |
| 9 | +### Installation |
| 10 | + |
| 11 | +You can install the package via composer: |
| 12 | + |
| 13 | +```bash |
| 14 | +composer require cleaniquecoders/laravel-media-secure |
| 15 | + |
| 16 | +``` |
| 17 | +Publish the config file with: |
| 18 | + |
| 19 | +```bash |
| 20 | +php artisan vendor:publish --tag="media-secure-config" |
| 21 | + |
| 22 | +``` |
| 23 | +### Usage |
| 24 | + |
| 25 | +In case you want more control on who are able to access to the media, you can use the [Laravel Policy](https://laravel.com/docs/12.x/authorization#creating-policies). You just need to define the policy, then it's done. This package will use the policy to handle more sophisticated and complex rules accessing to your media files. |
| 26 | + |
| 27 | +Make sure you are using [Laravel Medialibrary](https://spatie.be/docs/laravel-medialibrary/v10/introduction) package. |
| 28 | + |
| 29 | +When the `require_auth` configuration is enabled (`'require_auth' => true`), the use who want to access to the media require to login. |
| 30 | + |
| 31 | +When the `strict` configuration is enabled (`'strict' => true`), the **parent model of the media** (`$media->model`) is **required to have its own policy** registered. |
| 32 | + |
| 33 | +This policy **must define** the access methods: |
| 34 | + |
| 35 | +* `view` |
| 36 | +* `stream` |
| 37 | +* `download` |
| 38 | + |
| 39 | +These methods will be used by `MediaPolicy` to determine whether the user is authorised to access the media. |
| 40 | + |
| 41 | +#### Why Is This Required? |
| 42 | + |
| 43 | +Since Spatie's Media Library uses polymorphic relationships, media items are attached to various parent models (e.g., `Document`, `Post`, `User`, etc.). |
| 44 | +To enforce fine-grained control, `MediaPolicy` delegates authorisation checks to the parent model’s policy. |
| 45 | + |
| 46 | +#### What You Must Do |
| 47 | + |
| 48 | +1. Create a policy for the parent model (e.g., `DocumentPolicy`). |
| 49 | + |
| 50 | +2. Define the following methods in that policy: |
| 51 | + |
| 52 | + * `view(User $user, Document $document)` |
| 53 | + * `stream(User $user, Document $document)` |
| 54 | + * `download(User $user, Document $document)` |
| 55 | + |
| 56 | + |
| 57 | +#### Example: `DocumentPolicy` |
| 58 | + |
| 59 | +```php |
| 60 | +namespace App\Policies; |
| 61 | + |
| 62 | +use App\Models\Document; |
| 63 | +use App\Models\User; |
| 64 | + |
| 65 | +class DocumentPolicy |
| 66 | +{ |
| 67 | + public function view(User $user, Document $document): bool |
| 68 | + { |
| 69 | + return $user->id === $document->user_id; |
| 70 | + } |
| 71 | + |
| 72 | + public function stream(User $user, Document $document): bool |
| 73 | + { |
| 74 | + return $user->id === $document->user_id; |
| 75 | + } |
| 76 | + |
| 77 | + public function download(User $user, Document $document): bool |
| 78 | + { |
| 79 | + return $user->id === $document->user_id; |
| 80 | + } |
| 81 | +} |
| 82 | + |
| 83 | +``` |
| 84 | +> These methods **must be defined** because `MediaPolicy` uses the value from the `MediaAccess` enum to call `Gate::allows($type, $media->model)`. |
| 85 | +
|
| 86 | +#### Register the Policy |
| 87 | + |
| 88 | +In your `AuthServiceProvider`: |
| 89 | + |
| 90 | +```php |
| 91 | +protected $policies = [ |
| 92 | + \App\Models\Document::class => \App\Policies\DocumentPolicy::class, |
| 93 | +]; |
| 94 | + |
| 95 | +``` |
| 96 | +#### What Happens If No Policy Exists? |
| 97 | + |
| 98 | +| Condition | Result | |
| 99 | +| ---------------- | ----------------------------------------------------------------- | |
| 100 | +| `strict = true` | Access will be denied if the parent model doesn't have a policy | |
| 101 | +| `strict = false` | Access will be granted without checking the parent model's policy | |
| 102 | + |
| 103 | +#### Summary |
| 104 | + |
| 105 | +| Requirement | Mandatory | When | |
| 106 | +| -------------------------------------------- | --------- | --------------------------------- | |
| 107 | +| Parent model has a policy | ✅ | When `strict = true` | |
| 108 | +| Defines `view`, `stream`, `download` methods | ✅ | For enum-based access control | |
| 109 | +| Policy registered in `AuthServiceProvider` | ✅ | Required by Laravel's Gate system | |
| 110 | + |
| 111 | +#### Helpers |
| 112 | + |
| 113 | +You upload / add media as documented in Laravel Medialibrary. Then to generate links: |
| 114 | + |
| 115 | +```php |
| 116 | +// Get the view URL |
| 117 | +// https://your-app.com/media/view/some-random-uuid |
| 118 | +$view_url = get_view_media_url($media); |
| 119 | + |
| 120 | +// Get the download URL |
| 121 | +// https://your-app.com/media/download/some-random-uuid |
| 122 | +$download_url = get_download_media_url($media); |
| 123 | + |
| 124 | +// Get the stream URL |
| 125 | +// https://your-app.com/media/stream/some-random-uuid |
| 126 | +$stream_url = get_stream_media_url($media); |
| 127 | + |
| 128 | +``` |
5 | 129 | ## Update Setup in README - 2025-07-16 |
6 | 130 |
|
7 | 131 | **Full Changelog**: https://github.com/cleaniquecoders/laravel-media-secure/compare/2.2.0...2.2.1 |
|
0 commit comments