1<?php 2 3namespace MediaWiki\Tests\Unit\Permissions; 4 5use MediaWiki\Permissions\Authority; 6use MediaWiki\Permissions\SimpleAuthority; 7use MediaWiki\Permissions\UltimateAuthority; 8use MediaWiki\User\UserIdentity; 9use MediaWiki\User\UserIdentityValue; 10 11/** 12 * Various useful Authority mocks. 13 */ 14trait MockAuthorityTrait { 15 16 /** 17 * Create mock ultimate Authority for anon user. 18 * 19 * @return Authority 20 */ 21 private function mockAnonUltimateAuthority(): Authority { 22 return new UltimateAuthority( new UserIdentityValue( 0, '127.0.0.1' ) ); 23 } 24 25 /** 26 * Create mock ultimate Authority for registered user. 27 * 28 * @return Authority 29 */ 30 private function mockRegisteredUltimateAuthority(): Authority { 31 return new UltimateAuthority( new UserIdentityValue( 42, 'Petr' ) ); 32 } 33 34 /** 35 * Create mock Authority for anon user with no permissions. 36 * 37 * @return Authority 38 */ 39 private function mockAnonNullAuthority(): Authority { 40 return new SimpleAuthority( new UserIdentityValue( 0, '127.0.0.1' ), [] ); 41 } 42 43 /** 44 * Create mock Authority for a registered user with no permissions. 45 * 46 * @return Authority 47 */ 48 private function mockRegisteredNullAuthority(): Authority { 49 return new SimpleAuthority( new UserIdentityValue( 42, 'Petr' ), [] ); 50 } 51 52 /** 53 * Create a mock Authority for anon user with $permissions. 54 * 55 * @param array $permissions 56 * @return Authority 57 */ 58 private function mockAnonAuthorityWithPermissions( array $permissions ): Authority { 59 return new SimpleAuthority( new UserIdentityValue( 0, '127.0.0.1' ), $permissions ); 60 } 61 62 /** 63 * Create a mock Authority for a registered user with $permissions. 64 * 65 * @param array $permissions 66 * @return Authority 67 */ 68 private function mockRegisteredAuthorityWithPermissions( array $permissions ): Authority { 69 return new SimpleAuthority( new UserIdentityValue( 42, 'Petr' ), $permissions ); 70 } 71 72 /** 73 * Create a mock Authority for a $user with $permissions. 74 * 75 * @param UserIdentity $user 76 * @param array $permissions 77 * @return Authority 78 */ 79 private function mockUserAuthorityWithPermissions( 80 UserIdentity $user, 81 array $permissions 82 ): Authority { 83 return new SimpleAuthority( $user, $permissions ); 84 } 85 86 /** 87 * Create a mock Authority for an anon user with all but $permissions 88 * @param array $permissions 89 * @return Authority 90 */ 91 private function mockAnonAuthorityWithoutPermissions( array $permissions ): Authority { 92 return $this->mockUserAuthorityWithoutPermissions( 93 new UserIdentityValue( 0, '127.0.0.1' ), 94 $permissions 95 ); 96 } 97 98 /** 99 * Create a mock Authority for a registered user with all but $permissions 100 * @param array $permissions 101 * @return Authority 102 */ 103 private function mockRegisteredAuthorityWithoutPermissions( array $permissions ): Authority { 104 return $this->mockUserAuthorityWithoutPermissions( 105 new UserIdentityValue( 42, 'Petr' ), 106 $permissions 107 ); 108 } 109 110 /** 111 * Create a mock Authority for a $user with all but $permissions 112 * @param UserIdentity $user 113 * @param array $permissions 114 * @return Authority 115 */ 116 private function mockUserAuthorityWithoutPermissions( 117 UserIdentity $user, 118 array $permissions 119 ): Authority { 120 return $this->mockAuthority( 121 $user, 122 function ( $permission ) use ( $permissions ) { 123 return !in_array( $permission, $permissions ); 124 } 125 ); 126 } 127 128 /** 129 * Create mock Authority for anon user where permissions are determined by $callback. 130 * 131 * @param callable $permissionCallback 132 * @return Authority 133 */ 134 private function mockAnonAuthority( callable $permissionCallback ): Authority { 135 return $this->mockAuthority( 136 new UserIdentityValue( 0, '127.0.0.1' ), 137 $permissionCallback 138 ); 139 } 140 141 /** 142 * Create mock Authority for registered user where permissions are determined by $callback. 143 * 144 * @param callable $permissionCallback 145 * @return Authority 146 */ 147 private function mockRegisteredAuthority( callable $permissionCallback ): Authority { 148 return $this->mockAuthority( 149 new UserIdentityValue( 42, 'Petr' ), 150 $permissionCallback 151 ); 152 } 153 154 /** 155 * Create mock Authority for $user where permissions are determined by $callback. 156 * 157 * @param UserIdentity $user 158 * @param callable $permissionCallback ( string $permission, ?PageIdentity $page ) 159 * @return Authority 160 */ 161 private function mockAuthority( UserIdentity $user, callable $permissionCallback ): Authority { 162 $mock = $this->createMock( Authority::class ); 163 $mock->method( 'getUser' )->willReturn( $user ); 164 $methods = [ 'isAllowed', 'probablyCan', 'definitelyCan', 'authorizeRead', 'authorizeWrite' ]; 165 foreach ( $methods as $method ) { 166 $mock->method( $method )->willReturnCallback( $permissionCallback ); 167 } 168 $mock->method( 'isAllowedAny' ) 169 ->willReturnCallback( static function ( ...$permissions ) use ( $permissionCallback ) { 170 foreach ( $permissions as $permission ) { 171 if ( $permissionCallback( $permission ) ) { 172 return true; 173 } 174 } 175 return false; 176 } ); 177 $mock->method( 'isAllowedAll' ) 178 ->willReturnCallback( static function ( ...$permissions ) use ( $permissionCallback ) { 179 foreach ( $permissions as $permission ) { 180 if ( $permissionCallback( $permission ) ) { 181 return false; 182 } 183 } 184 return true; 185 } ); 186 return $mock; 187 } 188} 189