热搜词
发表于 2022-8-27 08:07:49 | 显示全部楼层 |阅读模式
Veno-File-Manager (VFM4)云盘,添加仅限游客和用户访问公共目录

功能概述:
1.添加游客和所有用户都可以访问的公共目录(public_dirs),所有用户只有读取权限,不能编辑与删除目录和文件。
2.添加仅限用户访问的公共目录(user_read_dirs),游客无权访问,所有用户只有读取权限,不能编辑与删除目录和文件。

已实现功能:
1.游客和登录用户,对公共目录(public_dirs)内的文件,有查看、分享和下载权限(需后台开启相关权限)。
2.游客和登录用户,对公共目录(public_dirs)内的文件,没有编辑、移动、复制、删除等权限。
3.游客和登录用户,能列表显示公共目录(public_dirs)及子目录内容。
4.登录用户,显示用户私有文件夹,并且有读写权限(需后台开启相关权限)。
5.游客身份,只能查看、分享和下载公共文件夹内容,无权查看用户私有文件夹(目录)。
6.游客和登录用户,能显示根目录下的所有文件,官方程序没有此功能。
7.增加一个仅限所有登录用户只读可公共目录(user_read_dirs),游客无权查看此目录。
8.登录用户,对公共目录(public_dirs)内的文件和用户只读可公共目录(user_read_dirs),没有更名、编辑和删除权限。
9.超级管理员(superadmin)对所有目录和文件夹,都有更名、编辑、移动、复制、删除等权限。

解决方法:
1.新增游客公共目录(public_dirs)数组和用户只读公共目录(user_read_dirs)配置
打开 根目录/vfm-admin/config-master.php 文件,新添一个 'public_dirs'数组配置参数,代码如下:
  1. 'public_dirs' =>
  2. array (
  3. 0 => 'public',
  4. 1 => '游客只读公共目录',
  5. ),


  6. 'user_read_dirs' =>
  7. array (
  8. 0 => 'user_read_dirs',
  9. 1 => '用户只读公共目录',
  10. ),
复制代码

2.为游客公共目录(public_dirs)和用户只读公共目录(user_read_dirs)设置相应类中成员方法

打开 根目录/vfm-admin/class/class.location.php 文件,参考类中成员方法 editAllowed() 代码,新添 readtAllowed() 成员方法,代码如下:
  1. /**
  2. * 检查是否允许读取当前目录,
  3. * based on configuration settings
  4. *
  5. * @param string $relative relative path to index.php
  6. *
  7. * @return true/false
  8. */
  9. public function readAllowed($relative = false)
  10. {
  11.     global $setUp;
  12.     $totdirs = count($this->path);

  13.     $father = $this->getDir(false, true, false, $totdirs -1);
  14.     $hidden_dirs = $setUp->getConfig('hidden_dirs');
  15.     if (!$hidden_dirs) {
  16. return false;
  17.     }
  18.     if (in_array(basename($father), $hidden_dirs)) {
  19. return false;
  20.     }
  21.         if ($this->checkPublicDir($relative) === true) {
  22.             return true;
  23.                 }                        
  24.    return false;
  25. }
复制代码
再参考类中成员方法 checkUserDir 代码,新添 checkPublicDir 成员方法,代码如下:
  1. /**
  2.   * 检查目录是否可供用户使用
  3.   *
  4.   * @param string $relative relative path to index.php
  5.   *
  6.   * @return true/false
  7.   */
  8. public function checkPublicDir($relative = false)
  9. {
  10.      global $gateKeeper;
  11.      global $setUp;

  12.      $thispath = $this->getDir(true, false, false, 0, $relative);
  13.      if (!is_dir(realpath($thispath))) {
  14.   return false;
  15.      }
  16.                         
  17.      $startdir = $setUp->getConfig('starting_dir');
  18.      $publicdirsarray = $setUp->getConfig('public_dirs') !== null ? $setUp->getConfig('public_dirs') : array();
  19.      $thiscleanpath = ltrim($thispath, './');
  20.      $cleanstartdir = rtrim(ltrim($startdir, './'), '/');
  21.      $thispatharray = explode('/', $thiscleanpath);
  22.      $checkpath = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? $thispatharray[1] : $thispatharray[0];
  23.      $pathcounter = $thispatharray[0] === $cleanstartdir && strlen($cleanstartdir) ? (int)2 : (int)1;        
  24.                                                 
  25.                         //检查分配的多个公共目录'public_dirs'文件夹
  26.      foreach ($publicdirsarray as $value) {

  27.   //检查是否分配了子/子文件夹
  28.   $userdirarray = explode('/', $value);
  29.   $usersubs = count($userdirarray) - 1;
  30.   if ($usersubs > 0) {
  31.       $subscounter = $usersubs + $pathcounter;
  32.       for ($i = $pathcounter; $i < $subscounter; $i++) {
  33.    $checkpath .= '/'.$thispatharray[$i];
  34.       }
  35.   }

  36.   //最后,检查用户是否可以访问该位置
  37.   if ($value === $checkpath) {
  38.       return true;
  39.   }
  40.                         }
  41.                                 
  42.                                 /* 检查当前路径是否根目录,是返回真,如果运行此段代码,根目录下所有文件后子目录都显示,包括用户私有文件夹;
  43.   如果注释掉此段代码,可实现根目录下只显示公共目录,无权查看用户私有目录,但是根目录下的所有文件也不显示。 */
  44.                                 // $thispath = $this->getDir(true, false, false, 0);
  45.                                 // if ($thispath === $setUp->getConfig('starting_dir')) {
  46.                                 // return true;
  47.                                 // }
  48.      return false;
  49. }
复制代码

3.修改前端显示UI代码,让游客和登录用户显示公共目录(public_dirs)和根目录(starting_dir)中的文件
打开根目录 vfm-admin/template/list-files.php 文件,把条件判断语句改为如下格式:
  1. $getDir = $location->getDir(true, false, false, 0, false);
  2. $cleangetDir = rtrim(ltrim($getDir, './'), '/');
  3. $startdir = './'.$setUp->getConfig('starting_dir');
  4. $cleanstartdir = rtrim(ltrim($startdir, './'), '/');

  5. if ($gateKeeper->isAccessAllowed()){
  6. if( $location->editAllowed()
  7.     || $location->guestReadtAllowed()
  8.     || $location->userReadtAllowed()  
  9.     && $gateKeeper->isUserLoggedIn()
  10.     || $cleangetDir === $cleanstartdir) {
  11.     if ($gateKeeper->isAllowed('view_enable'))
  12. {
  13.   列表显示文件代码 }
  14.   显示上传文件功能区块代码 }
  15. }
复制代码

解决浏览公共目录(user_read_dirs)下文件时时,“多选操作”菜单中仍显示移动、复制和删除按钮的问题;解决PC列表模式下显示公共目录(user_read_dirs)下文件时时,表格仍显示重命名和删除列的问题;
解决方法详见:http://www.admin365.cn/thread-46442-1-1.html(Veno-File-Manager (VFM4)云盘,增加用户只读游客无权限公共目录)
多选操作.png

不显示表格中编辑和删除列.png

4.修改ajax请求代码,使游客和登录用户能获取到公共目录(public_dirs)和根目录(starting_dir)中的文件
打开根目录  /vfm-admin/ajax/get-files.php  文件,查找如下代码:
  1. if ($gateKeeper->isAccessAllowed() && $location->editAllowed('../../') && $gateKeeper->isAllowed('view_enable'))
  2. {
  3. $fullpath = $location->getFullPath();
  4. ...
  5. }
复制代码
改为如下代码:
  1. $cleanlocdir = rtrim(ltrim($locdir, './'), '/');
  2. $startdir = './'.$setUp->getConfig('starting_dir');
  3. $cleanstartdir = rtrim(ltrim($startdir, './'), '/');

  4. if ($cleanlocdir === $cleanstartdir
  5. || $gateKeeper->isAccessAllowed()
  6. && $location->guestReadtAllowed('../../')  
  7. || $location->editAllowed('../../')  
  8. || $location->userReadtAllowed('../../')
  9. && $gateKeeper->isAllowed('view_enable')) {
  10.     $fullpath = $location->getFullPath();
  11. ...
  12. }
复制代码


解决平铺视图模式下显示公共目录(user_read_dirs)下文件时时,在文件右上角显示重命名和删除按钮问题;
解决PC浏览器打开公共目录(user_read_dirs)时,在文件列表右侧显示重命名和删除按钮问题;
解决手机端打开公共目录(user_read_dirs)时,在文件列表右侧显示重命名和删除按钮问题;
解决方法详见:http://www.admin365.cn/thread-46442-1-1.html(Veno-File-Manager (VFM4)云盘,增加用户只读游客无权限公共目录)

平铺模式-去掉删除按钮.png

pc-去掉删除按钮.png

手机版-去掉删除按钮.png

5.修改文件夹类,把公共目录(public_dirs)添加进用户目录
打开  根目录/vfm-admin/class/class.dirs.php   文件,查找数组变量 $userpatharray ,代码如下:
  1. $userpatharray = $gateKeeper->getUserInfo('dir') !== null ? json_decode($gateKeeper->getUserInfo('dir'), true) : false;
复制代码

把公共目录(public_dir)添加进去$userpatharray数组中,修改后代码为:
  1. $userpatharray = $gateKeeper->getUserInfo('dir') !== null ? json_decode($gateKeeper->getUserInfo('dir'), true) : false;
  2. $public_dirs = $setUp->getConfig('public_dirs');
  3. @$userpatharray = array_merge($userpatharray,$public_dirs);
复制代码

再查找仅获取用户分配的文件夹(如果有)遍历语句,增加一个 && !$this->location->readAllowed($relative) 条件,修改后如下:
  1. if (is_array($content)) {
  2.     foreach ($content as $item) {

  3.         if (is_dir($item)) {

  4.             $mbitem = Utils::mbPathinfo($item);
  5.             $item_basename = $mbitem['basename'];

  6.             // get only users' assigned folders if any
  7.             if ($userpatharray
  8.             && !in_array($item_basename, $userpatharray)
  9.             && !$this->location->editAllowed($relative)
  10.             && !$this->location->readAllowed($relative)) {
  11. continue;
  12.             }
  13.         
  14.             // Skip /vfm-admin/ if the main uploads dir is the root
  15.             if (!$hidefiles || ($hidefiles && !in_array($item_basename, $hidden_dirs))) {
  16. $this->dirs[] = new Dir($item_basename, $this->location, $relative);
  17.             }
  18.         }
  19.     }
  20. }
复制代码

6.为游客设置可查看公共目录(public_dirs)目录方法
打开 主目录/vfm-admin/class/class.gatekeeper.php文件,查找 getUserInfo($info) 函数,大概在257行左右,代码如下:
  1.         /**
  2.          * Get user info ('name', 'role', 'dir', 'email')
  3.          *
  4.          * @param int $info index of corresponding user info
  5.          *
  6.          * @return info requested
  7.          */
  8.         public function getUserInfo($info)
  9.         {
  10.             if ($this->isUserLoggedIn()
  11.                 && isset($_SESSION['vfm_user_name'])
  12.                 && strlen($_SESSION['vfm_user_name']) > 0
  13.             ) {
  14.                 $username = $_SESSION['vfm_user_name'];
  15.                 $curruser = $this->getCurrentUser($username);

  16.                 if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
  17.                     return $curruser[$info];
  18.                 }
  19.             }
  20.             return null;
  21.         }
复制代码
修改为如下代码:
  1.         /**
  2.          * Get user info ('name', 'role', 'dir', 'email')
  3.          *
  4.          * @param int $info index of corresponding user info
  5.          *
  6.          * @return info requested
  7.          */
  8.         public function getUserInfo($info)
  9.         {
  10.                         global $setUp;
  11.             if ($this->isUserLoggedIn()
  12.                 && isset($_SESSION['vfm_user_name'])
  13.                 && strlen($_SESSION['vfm_user_name']) > 0
  14.             ) {
  15.                 $username = $_SESSION['vfm_user_name'];
  16.                 $curruser = $this->getCurrentUser($username);

  17.                 if (isset($curruser[$info]) && strlen($curruser[$info]) > 0) {
  18.                     return $curruser[$info];
  19.                 }
  20.             }
  21.                          //游客可访问公共目录(public_dirs)内容
  22.                          else  {
  23.                                 $public_dirs = $setUp->getConfig('public_dirs');
  24.                                 $public_dirs = '["' . join('","', array_values($public_dirs) ) . '"]';
  25.                                 return $public_dirs;                                          
  26.                             }
  27.             return null;
  28.         }
复制代码
7.解决游客文件分享按钮不显示问题
打开  class.gatekeeper.php 文件,查找 isAllowed($action)  对象方法,把其中的   $role = $role == null ? 'guest' : $role;  三目运算符条件判断改动一下,修改后代码为:
  1.         /**
  2.          * Check if target action is allowed
  3.          *
  4.          * @param string $action action to check
  5.          *
  6.          * @return true/false
  7.          */
  8.         public function isAllowed($action)
  9.         {
  10.             global $setUp;
  11.             if ($action && $this->isAccessAllowed()) {
  12.                 $role = $this->getUserInfo('role');
  13.                 // $role = $role == null ? 'guest' : $role;
  14.                 $role = !$this-> isUserLoggedIn() ? 'guest' : $role;

  15.                 if ($role == 'superadmin') {
  16.                     return true;
  17.                 }

  18.                 $base_actions = array(
  19.                     'view_enable',
  20.                     'viewdirs_enable',
  21.                     'download_enable',
  22.                 );

  23.                 // Base actions true for all except Guest and User
  24.                 if (in_array($action, $base_actions) && $role !== 'guest' && $role !== 'user') {
  25.                     return true;
  26.                 }

  27.                 $role_ext = $role == 'admin' ? '' : '_'.$role;

  28.                 return $setUp->getConfig($action.$role_ext);
  29.             }
  30.             return false;
  31.         }
复制代码

8.让网页标题(title)动态显示为当前路径
打开 根目录/index.php 文件,查找网页标签<title>,并修改为:

  1. <?php
  2. $pathname = basename($location->getDir(true, false, false, 0, false));
  3. $father = basename($location->getDir(false, false, false, 1));
  4. ?>
  5. <title><?php print $pathname." | ".$father." | ".$setUp->getConfig('appname'); ?></title>
复制代码

9.解决中文目录无法上传文件bug
打开 根目录/vfm-admin/ajax/chunk.php  文件,查找如下一行代码:
  1. $getloc = $getloc ? ltrim(base64_decode($getloc), './') : false;
复制代码
在此段代码前添如如下一段代码:
  1. $getloc = str_replace(' ','+',$getloc);
复制代码

与解决此漏洞相关文件:
根目录/vfm-admin/config-master.php                   //配置文件
根目录/vfm-admin/class/class.location.php           //检查当前用户目录权限(修改此文件)
根目录/vfm-admin/class/class.dirs.php                //遍历所有用户私有文件夹下的子目录,使可以列表显示
根目录/vfm-admin/template/list-files.php            //前端文件列表显示UI模板
根目录/vfm-admin/class/class.gatekeeper.php     //验证当前用户权限的类
根目录 /vfm-admin/ajax/get-files.php                //显示文件相关权限按钮

待实现功能:
1.解决管理员自定义设置的隐藏文件和文件夹,如果在公共目录内,游客和登录用户仍然显示的bug。

全部评论4
灰儿 发表于 2022-9-29 15:07:36 | 显示全部楼层
http://www.admin365.cn/thread-46373-1-1.html  
Veno-File-Manager (VFM4)云盘,添加仅限游客和用户访问公共目录

http://www.admin365.cn/thread-46386-1-1.html  
Veno-File-Manager (VFM4)云盘让登录用户可显示公共文件夹方法

http://www.admin365.cn/thread-46442-1-1.html
Veno-File-Manager (VFM4)云盘,增加用户只读游客无权限公共目录
回复

使用道具 举报

回复
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|Archiver|手机版|小黑屋|管理员之家 ( 苏ICP备2023053177号-2 )

GMT+8, 2024-12-27 20:02 , Processed in 0.142404 second(s), 28 queries .

Powered by Discuz! X3.5

Cpoyright © 2001-2024 Discuz! Team