Role-profiles are no merged in case user has more role related to Imce

Created on 19 September 2021, about 3 years ago
Updated 25 August 2023, about 1 year ago

Problem/Motivation

Role-profiles are no merged in case user has more role related to Imce

Steps to reproduce

  • Create two roles for user
  • create two role profiles with different folders
  • login
  • open imce browser
  • folders are shown for one profile only

Proposed resolution

userProfile function should merge profiles. I made fix when merging folders but it is not 100% accurate as profile differs with quota, etc. So the browser should ask for scheme + resource to get correct profile params (mainly for upload)

Remaining tasks

User interface changes

API changes

Data model changes

πŸ’¬ Support request
Status

Active

Version

3.0

Component

Code

Created by

πŸ‡¨πŸ‡ΏCzech Republic tma0

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡©πŸ‡ͺGermany thomas.wardin

    Sorry for asking: Is such a plugin existing? How to install/make available to the module? How to protect against overwriting by updates?

  • Status changed to Active about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States josh.estep

    My issue, perhaps appropriate for this thread, was that I need to be able to support multiple IMCE configuration profiles associated with a given user where each profile assigns different permissions to a single folder.

    To solve this, I updated userProfile() in IMCE.php to iterate over the different permissions for a given folder and then merge.

    +        // Get IMCE settings and role-profile mappings
    +        $imce_settings = \Drupal::config('imce.settings');
    +        $storage = \Drupal::entityTypeManager()->getStorage('imce_profile');
    +        $roles_profiles = $imce_settings->get('roles_profiles');
    +        $user_roles = array_flip($user->getRoles());
    +
    +        // Initialize an array to hold the most permissive permissions for each folder
    +        $folder_perms = [];
    +
    +        // Loop through user roles to get profile configurations
    +        foreach ($user_roles as $rid => $role) {
    +          // Check if the role has a profile mapping
    +          if (isset($role) && !empty($roles_profiles[$rid][$scheme])) {
    +            // Load the IMCE profile and its config
    +            $test_config = $storage->load($roles_profiles[$rid][$scheme]);
    +            $profile_config = $test_config->getConf();
    +
    +            // Loop through folders in profile to keep the most permissive permissions
    +            foreach ($profile_config['folders'] as $folder) {
    +              $path = $folder['path'];
    +              if (!isset($folder_perms[$path])) {
    +                $folder_perms[$path] = [];
    +              }
    +              foreach ($folder['permissions'] as $perm => $value) {
    +                // Store the most permissive value of each permission
    +                if ($perm === 'all' || !isset($folder_perms[$path][$perm]) || $value > $folder_perms[$path][$perm]) {
    +                  $folder_perms[$path][$perm] = $value;
    +                }
    +              }
    +            }
    +          }
    +        }
    +
    +        // Convert the permissive permissions back to the original folder array format
    +        $conf['folders'] = [];
    +        foreach ($folder_perms as $path => $permissions) {
    +          $conf['folders'][] = ['path' => $path, 'permissions' => $permissions];
    +        }
    
           return static::processUserConf($conf, $user);
    

    This probably needs to be updated to use dependency injection, but I hope this helps somebody else.

  • Here is a sample plugin for above.

    Note it would break complex permissions, for example block rules below or beside allow rules.

    web/modules/custom/zzz/src/Plugin/ImcePlugin/ZzzImceFolders.php

    
    namespace Drupal\zzz\Plugin\ImcePlugin;
    
    
    use Drupal\Core\Session\AccountProxyInterface;
    use Drupal\imce\Imce;
    use Drupal\imce\ImcePluginBase;
    
    /**
     * Custom IMCE folder perms merge.
     *
     * @ImcePlugin(
     *   id = "zzz_imce_folders",
     *   label = "IMCE ZZZ Folders",
     *   weight = 10,
     * )
     *
     * Explain.
     */
    class ZzzImceFolders extends ImcePluginBase {
    
      /**
       * {@inheritdoc}
       */
      public function processUserConf(array &$conf, AccountProxyInterface $user) {
    
        // Skip administrators.
        if ($user->hasPermission("administer imce")) {
          return;
        }
    
        // Skip admin roles.
        if (array_intersect($user->getRoles(), [
          'administrator',
          'custom_client_admin',
        ])) {
          return;
        }
    
        // Get imce settings.
        $settings = \Drupal::config('imce.settings');
        $imce_roles = $settings->get('roles_profiles');
    
        // Get user roles, from more permissive to less permissive.
        $user_roles = array_reverse(array_flip($user->getRoles()));
        $user_imce_roles = array_keys(array_intersect_key($imce_roles, $user_roles));
    
        // Get storage.
        $scheme = \Drupal::config('system.file')->get('default_scheme');
        $storage = \Drupal::entityTypeManager()->getStorage('imce_profile');
    
        // Get folders for each role.
        foreach ($user_imce_roles as $id) {
          if ($profile = $storage->load($imce_roles[$id][$scheme])) {
            if ($folders = $profile->getConf('folders', [])) {
              $processed = Imce::processUserFolders($folders, $user);
              $conf['folders'][$id] = $processed;
            }
          }
        }
      }
    
    }
    
Production build 0.71.5 2024