Add a user in Cockpit and change access rights with the Cockpit GROUPS plugin - Bugs with Assets / Finder modules

Hello,

I want to create a new user in Cockpit so that my client can update his site himself. Of course, I want my client to have limited access to Cockpit’s features.

So I downloaded and installed this plugin : Groups Management UI Addon for Cockpit, which works perfectly… except for two things :

Indeed, I want to block the Assets module (because Cockpit, via this module, stores files both on the server in folders and subfolders (e.g. : ./year/month/day/filename.jpg)… but in the backend, files can be ordered only in virtual folders and subfolders. The structure created in the backend (ex: ./project-1/portraits/filename.jpg) will not be taken over on the server and the file will be stored in the root of the storage folder (ex: ./storage/uploads/filename.jpg instead of ./storage/uploads/project-1/portraits/filename.jpg) and I don’t like this)… but this was not provided in this plugin. I looked into the plugin’s source code, and even though I’m used to big frameworks (Symfony), I found it quite complicated to understand how it works internally.

I simply added this in the plugin file : cockpit_GROUPS/Groups/views/group.php (based on this source code) :

<div class="uk-margin-small-top">
   <field-boolean bind="group.cockpit.assets" label="@lang('Assets')"></field-boolean>
</div>

But it doesn’t work

Another problem, with this plugin it’s normally possible to block or not the Finder module and make changes to it (like specifying a default storage folder). The big problem is that when I log in with my client’s user account and try to use the Finder module… I get an error message “An error has occurred”. I don’t know what the problem is.

Do you have any ideas on how to solve these problems ?

Thanks in advance !

For your information, I managed to block access to the Assets module.

Here are the files I modified :

In the plugin, I added this above this code lines

<div class="uk-margin-small-top">
   <field-boolean bind="group.cockpit.assets" label="@lang('Assets')"></field-boolean>
</div>

And, in Cockpit

I modified this first file changing by this section of code :

@hasaccess?('cockpit', 'assets')
   <li class="uk-grid-margin">
      <a class="uk-display-block uk-panel-card-hover uk-panel-box uk-panel-space {{ (strpos($app['route'],'/assetsmanager')===0) ? 'uk-bg-primary uk-contrast':'' }}" href="@route('/assetsmanager')">
         <div class="uk-svg-adjust">
            <img class="uk-margin-small-right inherit-color" src="@base('assets:app/media/icons/assets.svg')" width="40" height="40" data-uk-svg alt="assets" /> 
         </div>
         <div class="uk-text-truncate uk-text-small uk-margin-small-top">@lang('Assets')</div>
      </a>
   </li>
@end

And this second file by this section of code

public function index() {

      if (!$this->module('cockpit')->hasaccess('cockpit', 'assets')) {
         return $this->helper('admin')->denyRequest();
      }

      return $this->render('cockpit:views/assets/index.php');
}

So, when I log in with my client’s account, the Assets module is no longer visible in the menu and the address xxx.fr/assetsmanager redirects to a page “Sorry, you are not authorized.” ! Great !

The problem is that when I update Cockpit, I will have to redo everything. Is there a better solution so that it doesn’t skip the next update ?

The problem with the Finder module is still present. :frowning: :thinking: :sob:

Hello @MarcTabaries,

thanks for sharing your journey on making this work.

Yes, there are better/other ways to make such adjustments without having to change core code.

My suggestion for the no-assets functionality would be

  • a custom script in config/bootstrap.php
  • that checks if user has-access
  • on route it denies access to assetsmanager
  • on view load it applies some JS/CSS to hide links to the assetsmanager
// config/bootstrap.php

<?php

if (COCKPIT_ADMIN_CP) {
    
    $app->on('admin.init', function () {
        if (!$this->module('cockpit')->hasaccess('cockpit', 'assetsmanager')) {
            if ($this['route'] === '/assetsmanager') { // or better a preg_match to include sub-routes
                return $this->helper('admin')->denyRequest();
            }

            $app->on('admin.dashboard.header', function ($collectionName) {
                echo "
                    <style>
                    /* some CSS to hide the assets-manager links */
                    </style>
                ";
            });
        }
    });

}

(Note: not tested, but it should work along those lines)

Have a look into your error logs (e.g. apache error logs).
Where and how is this error shown?
Are there additional errors in the browser console?

Thank you for your feedback.

I understand your solution and will test it as soon as possible.

For the error message with the Finder module, the exact message is “Something went wrong”. The error is only displayed in the Cockpit backoffice. Nothing in the browser console. Nothing in the logs.

In attachement, a screenshot of the error message :

I don’t understand why block assets maybe what u mean block finder
here my settings for editor roles its block the finder ut not the assets
I dont use the addons

place in the settings maybe give u the idea

groups:
  editor:
    cockpit:
      backend: true
      settings: true
      rest: true
      webhooks: true
    singletons:
      manage: true
      delete: false
    forms:
      manage: true
    colletions:
      manage: true

Hello,

Thank you for your feedback.

I want to block the Assets module for two reasons:

1/ With the Assets module, files are stored on the server in folders and subfolders in the format ./storage/uploads/year/month/day/filename.jpg. In most of my projects, this structure does not suit me.

Here, for this project, it’s even truer… because my client is a photographer and it makes more sense for him to sort his photos by projects (./storage/uploads/project-1/filename.jpg) rather than by date (./storage/uploads/year/month/day/filename.jpg).

Another point, let’s imagine that my client adds photos on the server today with the Assets module (./storage/uploads/2021/10/30/filename.jpg), and that in a week, he decides to add other photos to this same project. The new photos would then be stored in a different folder (./storage/uploads/2021/11/10/filename.jpg), instead of being grouped together. This may seem trivial, but if one day we have to go through the backup folders… I let you imagine how difficult it is for me to know which pictures belong to which projects.

2/ With the Assets module, it is indeed possible to create folders and subfolders… but these folders are only virtual. The folder structure created in the Assets module is not copied to the server.

That’s why I don’t want to use the Assets module.

I will try to see if the problem is solved by using @abernh’s solution and by stopping using the Cockpit GROUPS plugin.

I will keep you posted.

Re,

Here is what I have managed to do without use Cockpit GROUPS plugin. It’s a bit of a fiddle, but it works. I don’t know what you think…

// in : config/bootstrap.php

<?php
if (COCKPIT_ADMIN_CP) {
    $app->on('admin.init', function() use($app) {
        // CHECKS IF THE USER IS NOT AN ADMINISTRATOR
        if ($this->helper('admin')->user['group'] != 'admin') {

            // IF THE USER TRIES TO ACCESS THE ./ASSETSMANAGER PAGE, AN ERROR MESSAGE IS SHOWN
            $this->bind('/assetsmanager', function() {
                return $this->helper('admin')->denyRequest(); // or : $this->reroute('/');
            });

            // WE ALSO BLOCK ACCESS TO THE ASSETS MODULE WHEN WE ARE IN A COLLECTION / SINGLETON MODULES
            $app->on('cockpit.assets.list' , function () {
                return cockpit()->stop('{"error": "You can\'t use this module."}', 401);
            });

            $app->on('cockpit.assets.save' , function () {
                return cockpit()->stop('{"error": "You can\'t use this module."}', 401);
            });

            $app->on('cockpit.assets.remove' , function () {
                return cockpit()->stop('{"error": "You can\'t use this module."}', 401);
            });

            // FOR MORE SECURITY WE HIDE THE LINK TO THE ASSETS MODULE 
            // IN THE MENU OF COCKPIT AND IN THE COLLECTION / SINGLETON MODULES
            $app->on('app.layout.header', function() {
                echo "<style>
                    .app-menu-container .uk-grid-margin:nth-child(2),
                    cp-field[type='image'] .uk-margin-top a:nth-child(2) { 
                        display: none;
                        visibility: hidden; 
                    }
                </style>";
            });
        }
    });
}

Bye.

1 Like