Plugin development: how can I check if user has the permissions to delete only his own assets? I have a front-end form where logged users can upload and delete their personal files.

These users have the strict minimum permissions required to interact with this form. They can only Create, Publish and Delete their own entries in the section where the form create these entries.

In order to be able to delete these files from Craft (and not from only the field they're linked in this entry), I have created this custom action in a module:

&lt;?php

namespace modules\mymodule\controllers;

use Craft;
use craft\web\Controller;
use craft\elements\Asset;

class DefaultController extends Controller
{

    public function actionDeleteAsset()
    {
        $this-&gt;requireAcceptsJson();
        $this-&gt;requireLogin();

        $currentUser = Craft::$app-&gt;getUser()-&gt;getIdentity();
        if (!$currentUser) {
            return $this-&gt;asErrorJson(Craft::t('app', 'Only a logged in user can delete an asset.'));
        } else {
            $request = Craft::$app-&gt;getRequest();
            $assetId = $request-&gt;getParam('assetId', '');
            $asset = Craft::$app-&gt;getAssets()-&gt;getAssetById($assetId);

            if (!empty($asset)) {
                if (!Craft::$app-&gt;getUser()-&gt;checkPermission('deleteFilesAndFoldersInVolume:' . $asset-&gt;volumeId)) {
                    return $this-&gt;asErrorJson(Craft::t('app', 'You don\'t have permission to delete this asset.'));
                } else {
                    Craft::$app-&gt;getElements()-&gt;deleteElementById($asset-&gt;id, Asset::class);
                    return $this-&gt;asJson([
                        'success' =&gt; true
                    ]);
                }
            } else {
                return $this-&gt;asErrorJson(Craft::t('app', 'This asset does not exists or has already been deleted.'));
            }
        }
    }

}


The problem is that Craft::$app-&gt;getUser()-&gt;checkPermission('deleteFilesAndFoldersInVolume:' . $asset-&gt;volumeId)is not entirely appropriate:


I need to add Volume permissions (View volume + Remove files and
folders) to these users to allow them to delete their assets from the
front-end form ;
By adding these permissions, they have access to
other users' assets, which is a security problem ;


So how can I check if user has the permissions to delete only his own assets? In other words, this user can only interact with the assets he has uploaded.
Thanks to @RobinSchambach advices, I was able to find a safe solution to handle this permission problematic.

This is possible using two main addings:


Register a new custom permission from the plugin


This prevents user from be able to access other users assets

Add a custom User field on the assets to assign ownership ;


Using this we can verify that it was uploaded from user requesting the file deletion



In the plugin Service:

public function linkUserToAssets($assets = [])
{
    $currentUser = Craft::$app-&gt;getUser()-&gt;getIdentity();
    if ($currentUser &amp;&amp; Craft::$app-&gt;request-&gt;getIsSiteRequest()
        &amp;&amp; Craft::$app-&gt;request-&gt;getIsPost()) {
        foreach ($assets-&gt;all() as $asset) {
            if (isset($asset-&gt;id) &amp;&amp; !empty($asset-&gt;id)) {
                $asset = Craft::$app-&gt;assets-&gt;getAssetById($asset-&gt;id);
                if (isset($asset-&gt;assetsOwner)) {
                    $asset-&gt;assetsOwner = [$currentUser-&gt;id];
                    Craft::$app-&gt;elements-&gt;saveElement($asset);
                }
            }
        }
    }
}


This adds a function to call before each entry is saved, to assign the user's ownership on entry's assets using the assetsOwner custom field.

In the plugin Module:

Event::on(
    UserPermissions::class,
    UserPermissions::EVENT_REGISTER_PERMISSIONS,
    function(RegisterUserPermissionsEvent $event) {
        $event-&gt;permissions['User'] = [
            'deleteOwnAssets' =&gt; [
                'label' =&gt; 'Delete Own Assets'
            ],
        ];
    }
);


This adds a custom permission in the CP which should be added to group of users who will perform this action.

In the plugin Controller:

public function actionDeleteAsset()
{
    $currentUser = Craft::$app-&gt;getUser()-&gt;getIdentity();
    if ($currentUser) {
        $request = Craft::$app-&gt;getRequest();
        $assetId = $request-&gt;getBodyParam('assetId');
        $asset = Craft::$app-&gt;getAssets()-&gt;getAssetById($assetId);

        if ($asset-&gt;assetsOwner[0]-&gt;id !== $currentUser-&gt;id || !Craft::$app-&gt;user-&gt;checkPermission('deleteOwnAssets')) {
            return $this-&gt;asErrorJson(Craft::t('app', self::TEXT_PERMISSION_REQUIRED));
        }
    }
}


This deletes requested assets if the current user was the owner of the asset (using assetsOwner custom field) and has the required custom permission (in this case, deleteOwnAssets).