WordPress.org

Make WordPress Core

Ticket #29544: 0001-added-permissions-to-mock-file-system-and-is_readabl.patch

File 0001-added-permissions-to-mock-file-system-and-is_readabl.patch, 15.8 KB (added by mnelson4, 7 years ago)

a different git patch that also adds is_readable() and is_writable() to mock filesystem

  • tests/phpunit/includes/mock-fs.php

    From a58985470d4560fd4952f5dc31e63d9e15e72d06 Mon Sep 17 00:00:00 2001
    From: Michael Nelson <michael@eventespresso.com>
    Date: Fri, 5 Sep 2014 15:45:56 -0700
    Subject: [PATCH] added permissions to mock file system and is_readable and
     is_writable methods
    
    ---
     tests/phpunit/includes/mock-fs.php             | 272 ++++++++++++++++++++++++-
     tests/phpunit/tests/filesystem/permissions.php | 108 ++++++++++
     2 files changed, 374 insertions(+), 6 deletions(-)
     create mode 100644 tests/phpunit/tests/filesystem/permissions.php
    
    diff --git a/tests/phpunit/includes/mock-fs.php b/tests/phpunit/includes/mock-fs.php
    index 8873b5c..200b5c7 100644
    a b  
    11<?php
     2define( 'WP_Filesystem_MockFS_default_perms' , '0777' );
     3define( 'WP_Filesystem_MockFS_default_owner' , 'wp-owner' );
     4define( 'WP_Filesystem_MockFS_default_group' , 'wp-group' );
    25class WP_Filesystem_MockFS extends WP_Filesystem_Base {
    36        private $cwd;
    47
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    912        // a fast more efficient way of determining if a path exists, and access to that node
    1013        private $fs_map = array();
    1114
     15        private $_current_system_user_name;
     16        private $_system_users = array();
     17
    1218        public $verbose = false; // Enable to debug WP_Filesystem_Base::find_folder() / etc.
    1319        public $errors = array();
    1420        public $method = 'MockFS';
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    4551                $this->cache = array(); // Used by find_folder() and friends
    4652                $this->cwd = isset( $this->fs_map[ $home_dir ] ) ? $this->fs_map[ $home_dir ] : '/';
    4753                $this->setfs( $paths );
     54                $this->add_system_user( WP_Filesystem_MockFS_default_owner );
    4855        }
    4956
    5057        /**
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    7279
    7380        /**
    7481         * Locates a filesystem "node"
     82         * @return MockFS_Node
    7583         */
    7684        private function locate_node( $path ) {
    7785                return isset( $this->fs_map[ $path ] ) ? $this->fs_map[ $path ] : false;
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    99107                                return false;
    100108                }
    101109
    102                 $node = new MockFS_Directory_Node( $path );
     110                $node = new MockFS_Directory_Node( $path, $chmod, $chown, $chgrp );
    103111
    104112                $parent_node->children[ $node->name ] = $node;
    105113                $this->fs_map[ $path ] = $node;
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    109117
    110118        function put_contents( $path, $contents = '', $mode = null ) {
    111119                if ( ! $this->is_dir( dirname( $path ) ) )
    112                         $this->mkdir( dirname( $path ) );
     120                        $this->mkdir( dirname( $path ), $mode );
    113121
    114122                $parent = $this->locate_parent_node( $path );
    115                 $new_file = new MockFS_File_Node( $path, $contents );
     123                $new_file = new MockFS_File_Node( $path, $contents, $mode );
    116124
    117125                $parent->children[ $new_file->name ] = $new_file;
    118126                $this->fs_map[ $path ] = $new_file;
    class WP_Filesystem_MockFS extends WP_Filesystem_Base { 
    191199                return $ret;
    192200        }
    193201
     202        /**
     203         * Changes the permissions
     204         * @param string $file path to file/folder
     205         * @param string $mode
     206         * @param boolean $recursive
     207         * @return boolean success
     208         */
     209        public function chmod( $file, $mode = false, $recursive = false ) {
     210                $node = $this->locate_node( $file );
     211                if( ! $node instanceof MockFS_Node ){
     212                        return FALSE;
     213                }
     214                $node->perms = $mode;
     215                if( $node instanceof MockFS_Directory_Node && $recursive ){
     216                        foreach( $node->children as $child_node ){
     217                                $this->chmod( $child_node->path, $mode, $recursive );
     218                        }
     219                }
     220                return TRUE;
     221        }
     222        /**
     223         * CHanges the owner
     224         * @param string $file
     225         * @param string $owner name of owner
     226         * @param type $recursive
     227         */
     228        public function chown( $file, $owner, $recursive = false ) {
     229                $node = $this->locate_node( $file );
     230                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     231                        return FALSE;
     232                }
     233                $node->owner = $owner;
     234                if( $node instanceof MockFS_Directory_Node && $recursive ){
     235                        foreach( $node->children as $child_node ){
     236                                $this->chown( $child_node->path, $owner, $recursive );
     237                        }
     238                }
     239                return TRUE;
     240        }
     241        /**
     242         * Sets the group name
     243         * @param string $file
     244         * @param string $group
     245         * @param boolean $recursive
     246         * @return boolean success
     247         */
     248        public function chgrp( $file, $group, $recursive = false ) {
     249                $node = $this->locate_node( $file );
     250                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     251                        return FALSE;
     252                }
     253                $node->group = $group;
     254                if( $node instanceof MockFS_Directory_Node && $recursive ){
     255                        foreach( $node->children as $child_node ){
     256                                $this->chgrp( $child_node->path, $group, $recursive );
     257                        }
     258                }
     259                return TRUE;
     260        }
     261
     262        /**
     263         *
     264         * @param type $file
     265         * @return string | false on error
     266         */
     267        function owner( $file ) {
     268                $node = $this->locate_node( $file );
     269                if( ! $node instanceof MockFS_Node || ! $this->is_writable( $file ) ){
     270                        return FALSE;
     271                }else{
     272                        return $node->owner();
     273                }
     274        }
     275
     276        /**
     277         *
     278         * @param type $file
     279         * @return string | false on error
     280         */
     281        function group( $file ) {
     282                $node = $this->locate_node( $file );
     283                if( ! $node instanceof MockFS_Node ){
     284                        return FALSE;
     285                }else{
     286                        return $node->group();
     287                }
     288        }
     289
     290        /**
     291         * Gets the permissions on the file
     292         * @return string | false on error
     293         */
     294        public function getchmod( $file ){
     295                $node = $this->locate_node( $file );
     296                if( ! $node instanceof MockFS_Node ){
     297                        return FALSE;
     298                }else{
     299                        return $node->perms();
     300                }
     301        }
     302
     303        /**
     304         * Users to swithch to
     305         * @param string $new_username
     306         * @return boolean success
     307         */
     308        public function change_current_system_user( $new_username ){
     309                if( isset( $this->_system_users[ $new_username ] ) ){
     310                        $this->_current_system_user_name = $new_username;
     311                }else{
     312                        return FALSE;
     313                }
     314        }
     315        /**
     316         * Gets the current mock FS system user, or FALSE if none has been set
     317         * @return MockFS_System_User
     318         */
     319        public function get_current_system_user(){
     320                if( isset( $this->_system_users[ $this->_current_system_user_name ] ) ){
     321                        return $this->_system_users[ $this->_current_system_user_name ];
     322                }else{
     323                        return FALSE;
     324                }
     325        }
     326
     327        /**
     328         * Adds the specified user. Returns that new user obejct or FALSE
     329         * @param string $username
     330         * @param string $groupname
     331         * @return boolean|\MockFS_System_User
     332         */
     333        function add_system_user( $username, $groupname = NULL ){
     334                if( isset( $this->_system_users[ $username ] ) ){
     335                        return FALSE;
     336                }
     337                if( ! $groupname ){
     338                        $groupname = WP_Filesystem_MockFS_default_group;
     339                }
     340                $user = new MockFS_System_User( $username, $groupname );
     341                $this->_current_system_user_name = $user->username;
     342                $this->_system_users[ $user->username ] = $user;
     343                return $user;
     344        }
     345
     346        function is_readable( $file ) {
     347                $user = $this->get_current_system_user();
     348                $file_node = $this->locate_node( $file );
     349                $perms =  intval( $file_node->perms(), 8 ) ;
     350                //owned by this user
     351                if( $file_node->owner() == $user->username ) {
     352                        if( $perms & 0400 ){
     353//                              echo "\r\n " . $user->username . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     354                                return TRUE;
     355                        }
     356                }
     357                //owned by this group?
     358                if( $file_node->group == $user->groupname ) {
     359                        if( $perms & 0040 ) {
     360//                              echo "\r\n " . $user->groupname . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     361                                return TRUE;
     362                        }
     363                }
     364                if( $perms & 0004){
     365//                      echo "\r\n anyone has permision to read " . $file_node->name . " because its perms are :" . $perms;
     366                        return TRUE;
     367                }else{
     368                        return FALSE;
     369                }
     370        }
     371        function is_writable( $file ) {
     372                $user = $this->get_current_system_user();
     373                $file_node = $this->locate_node( $file );
     374                $perms =  intval( $file_node->perms(), 8 ) ;
     375                //owned by this user
     376                if( $file_node->owner() == $user->username ) {
     377                        if( $perms & 0200 ){
     378//                              echo "\r\n " . $user->username . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     379                                return TRUE;
     380                        }
     381                }
     382                //owned by this group?
     383                if( $file_node->group == $user->groupname ) {
     384                        if( $perms & 0020 ) {
     385//                              echo "\r\n " . $user->groupname . " has permision to read " . $file_node->name . " because its perms are :" . $perms;
     386                                return TRUE;
     387                        }
     388                }
     389                if( $perms & 0002){
     390//                      echo "\r\n anyone has permision to read " . $file_node->name . " because its perms are :" . $perms;
     391                        return TRUE;
     392                }else{
     393                        return FALSE;
     394                }
     395        }
     396        /**
     397         *
     398         * @param type $path
     399         * @param type $time
     400         * @param type $atime
     401         * @return boolean
     402         */
     403        function touch( $path, $time = 0, $atime = 0 ) {
     404                if( ! $this->exists(  $path ) ){
     405                        $this->put_contents($path);
     406                        return TRUE;
     407                }else{
     408                        //if we kept track of when a file was last edited we would update it
     409                        return TRUE;
     410                }
     411        }
     412
     413
    194414}
    195415
    196416class MockFS_Node {
    197417        public $name; // The "name" of the entry, does not include a slash (exception, root)
    198418        public $type; // The type of the entry 'f' for file, 'd' for Directory
    199419        public $path; // The full path to the entry.
     420        public $perms; //permissions associated with this file or folder
     421        public $owner; //the owner name of the file or folder
     422        public $group; //the group of this file or folder
    200423
    201         function __construct( $path ) {
     424        function __construct( $path, $chmod = NULL, $chown = NULL, $chgrp = NULL ) {
    202425                $this->path = $path;
    203426                $this->name = basename( $path );
     427                if( ! $chmod ) {
     428                        $chmod = WP_Filesystem_MockFS_default_perms;
     429                }
     430                if( ! $chown ) {
     431                        $chown = WP_Filesystem_MockFS_default_owner;
     432                }
     433                if( ! $chgrp ) {
     434                        $chgrp = WP_Filesystem_MockFS_default_group;
     435                }
     436                $this->perms = $chmod;
     437                $this->owner = $chown;
     438                $this->group = $chgrp;
    204439        }
    205440
    206441        function is_file() {
    class MockFS_Node { 
    210445        function is_dir() {
    211446                return $this->type == 'd';
    212447        }
     448        /**
     449         *
     450         * @return string @see http://en.wikipedia.org/wiki/File_system_permissions#Numeric_notation
     451         */
     452        function perms(){
     453                return $this->perms;
     454        }
     455        function owner(){
     456                return $this->owner;
     457        }
     458        function group(){
     459                return $this->group;
     460        }
    213461}
    214462
    215463class MockFS_Directory_Node extends MockFS_Node {
    class MockFS_File_Node extends MockFS_Node { 
    221469        public $type = 'f';
    222470        public $contents = ''; // The contents of the file
    223471
    224         function __construct( $path, $contents = '' ) {
    225                 parent::__construct( $path );
     472        function __construct( $path, $contents = '', $chmod = NULL, $chown = NULL, $chgrp = NULL ) {
     473                parent::__construct( $path, $chmod, $chown, $chgrp );
    226474                $this->contents = $contents;
    227475        }
     476}
     477
     478class MockFS_System_User{
     479        public $username;
     480        public $groupname;
     481        function __construct( $username, $groupname = NULL) {
     482                $this->username = $username;
     483                if( ! $groupname ){
     484                        $groupname = WP_Filesystem_MockFS_default_group;
     485                }
     486                $this->groupname = $groupname;
     487        }
    228488}
     489 No newline at end of file
  • new file tests/phpunit/tests/filesystem/permissions.php

    diff --git a/tests/phpunit/tests/filesystem/permissions.php b/tests/phpunit/tests/filesystem/permissions.php
    new file mode 100644
    index 0000000..bb12347
    - +  
     1<?php
     2/**
     3 *
     4 * permissions
     5 *
     6 * @package                     Event Espresso
     7 * @subpackage
     8 * @author                              Mike Nelson
     9 * @group filesystem
     10 */
     11class WP_Filesystem_permissions_UnitTestCases extends WP_Filesystem_UnitTestCase{
     12
     13        function test_mkdir(){
     14                global $wp_filesystem;
     15                $wp_filesystem->init('/');
     16                $folder_path = '/test/';
     17                $wp_filesystem->mkdir( $folder_path );
     18                $this->assertTrue( $wp_filesystem->exists( $folder_path ) );
     19                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ) );
     20                $this->assertEquals( WP_Filesystem_MockFS_default_owner, $wp_filesystem->owner( $folder_path ) );
     21                $this->assertEquals( WP_Filesystem_MockFS_default_group, $wp_filesystem->group( $folder_path ) );
     22        }
     23
     24        function test_chmod(){
     25                global $wp_filesystem;
     26                $wp_filesystem->init('/');
     27                $folder_path = '/test/';
     28                $wp_filesystem->mkdir( $folder_path );
     29                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ) );
     30                $wp_filesystem->chmod( $folder_path, 664 );
     31                $this->assertEquals( 664, $wp_filesystem->getchmod( $folder_path ) );
     32        }
     33
     34        function test_chown(){
     35                global $wp_filesystem;
     36                $wp_filesystem->init('/');
     37                $folder_path = '/test/';
     38                $wp_filesystem->mkdir( $folder_path );
     39                $this->assertEquals( WP_Filesystem_MockFS_default_owner, $wp_filesystem->owner( $folder_path ) );
     40                $wp_filesystem->chown( $folder_path, 'stranger');
     41                $this->assertEquals( 'stranger', $wp_filesystem->owner( $folder_path ) );
     42        }
     43
     44        function test_chgroup(){
     45                global $wp_filesystem;
     46                $wp_filesystem->init('/');
     47                $folder_path = '/test/';
     48                $wp_filesystem->mkdir( $folder_path );
     49                $this->assertEquals( WP_Filesystem_MockFS_default_group, $wp_filesystem->group( $folder_path ) );
     50                $success = $wp_filesystem->chgrp( $folder_path, 'globe-trotters');
     51                $this->assertEquals( 'globe-trotters', $wp_filesystem->group( $folder_path ) );
     52        }
     53
     54        function test_is_readable(){
     55                global $wp_filesystem;
     56                $wp_filesystem->init('/');
     57                $folder_path = '/test/';
     58                $wp_filesystem->mkdir( $folder_path );
     59                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ));
     60                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     61                //switch to another user, although they should be able to read it too
     62                $other_user_same_group =  $wp_filesystem->add_system_user( 'other_user_same_group', WP_Filesystem_MockFS_default_group );
     63                $other_user_other_group = $wp_filesystem->add_system_user( 'other_user_other_group', 'other_group' );
     64                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     65                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     66
     67                $wp_filesystem->change_current_system_user( WP_Filesystem_MockFS_default_owner );
     68                //change the permissions soo only someone in the same group can read
     69                $wp_filesystem->chmod( $folder_path, '770' );
     70                $this->assertEquals( '770', $wp_filesystem->getchmod( $folder_path ) );
     71                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     72                //and now check the user in the same group can still read...
     73                $wp_filesystem->change_current_system_user( $other_user_same_group->username );
     74                $this->assertTrue( $wp_filesystem->is_readable( $folder_path ) );
     75                //..bu tthe user in a differeng group can't
     76                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     77                $this->assertFalse( $wp_filesystem->is_readable( $folder_path ) );
     78        }
     79
     80        function test_is_writable(){
     81                global $wp_filesystem;
     82                $wp_filesystem->init('/');
     83                $folder_path = '/test/';
     84                $wp_filesystem->mkdir( $folder_path );
     85                $this->assertEquals( WP_Filesystem_MockFS_default_perms, $wp_filesystem->getchmod( $folder_path ));
     86                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     87                //switch to another user, although they should be able to write it too
     88                $other_user_same_group =  $wp_filesystem->add_system_user( 'other_user_same_group', WP_Filesystem_MockFS_default_group );
     89                $other_user_other_group = $wp_filesystem->add_system_user( 'other_user_other_group', 'other_group' );
     90                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     91                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     92
     93                $wp_filesystem->change_current_system_user( WP_Filesystem_MockFS_default_owner );
     94                //change the permissions soo only someone in the same group can read
     95                $wp_filesystem->chmod( $folder_path, '770' );
     96                $this->assertEquals( '770', $wp_filesystem->getchmod( $folder_path ) );
     97                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     98                //and now check the user in the same group can still write...
     99                $wp_filesystem->change_current_system_user( $other_user_same_group->username );
     100                $this->assertTrue( $wp_filesystem->is_writable( $folder_path ) );
     101                //..bu tthe user in a differeng group can't
     102                $wp_filesystem->change_current_system_user( $other_user_other_group->username );
     103                $this->assertFalse( $wp_filesystem->is_writable( $folder_path ) );
     104        }
     105
     106}
     107
     108// End of file permissions.php
     109 No newline at end of file