Differences Between: [Versions 310 and 403] [Versions 311 and 403] [Versions 39 and 403] [Versions 400 and 403] [Versions 401 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace repository_nextcloud; 18 19 use testable_access_controlled_link_manager; 20 21 defined('MOODLE_INTERNAL') || die(); 22 23 global $CFG; 24 require_once($CFG->libdir . '/webdavlib.php'); 25 require_once($CFG->dirroot . '/repository/nextcloud/tests/fixtures/testable_access_controlled_link_manager.php'); 26 27 /** 28 * Class repository_nextcloud_testcase 29 * 30 * @package repository_nextcloud 31 * @group repository_nextcloud 32 * @copyright 2017 Project seminar (Learnweb, University of Münster) 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class access_controlled_link_manager_test extends \advanced_testcase { 36 37 /** @var null|testable_access_controlled_link_manager a malleable variant of the access_controlled_link_manager. */ 38 public $linkmanager = null; 39 40 /** @var null|\repository_nextcloud\ocs_client The ocs_client used to send requests. */ 41 public $ocsmockclient = null; 42 43 /** @var null|\core\oauth2\client Mock oauth client for the system account. */ 44 private $oauthsystemmock = null; 45 46 /** @var null|\core\oauth2\issuer which belongs to the repository_nextcloud object. */ 47 public $issuer = null; 48 49 /** @var string system account username. */ 50 public $systemaccountusername; 51 52 /** 53 * SetUp to create an repository instance. 54 */ 55 protected function setUp(): void { 56 $this->resetAfterTest(true); 57 58 // Admin is necessary to create issuer object. 59 $this->setAdminUser(); 60 61 $generator = $this->getDataGenerator()->get_plugin_generator('repository_nextcloud'); 62 $this->issuer = $generator->test_create_issuer(); 63 $generator->test_create_endpoints($this->issuer->get('id')); 64 65 // Mock clients. 66 $this->ocsmockclient = $this->getMockBuilder(ocs_client::class 67 )->disableOriginalConstructor()->disableOriginalClone()->getMock(); 68 $this->oauthsystemmock = $this->getMockBuilder(\core\oauth2\client::class 69 )->disableOriginalConstructor()->disableOriginalClone()->getMock(); 70 $systemwebdavclient = $this->getMockBuilder(\webdav_client::class 71 )->disableOriginalConstructor()->disableOriginalClone()->getMock(); 72 $systemocsclient = $systemocsclient = $this->getMockBuilder(ocs_client::class 73 )->disableOriginalConstructor()->disableOriginalClone()->getMock(); 74 75 // Pseudo system account user. 76 $this->systemaccountusername = 'pseudouser'; 77 $record = new \stdClass(); 78 $record->issuerid = $this->issuer->get('id'); 79 $record->refreshtoken = 'pseudotoken'; 80 $record->grantedscopes = 'scopes'; 81 $record->email = ''; 82 $record->username = $this->systemaccountusername; 83 $systemaccount = new \core\oauth2\system_account(0, $record); 84 $systemaccount->create(); 85 86 $this->linkmanager = new testable_access_controlled_link_manager($this->ocsmockclient, 87 $this->oauthsystemmock, $systemocsclient, 88 $this->issuer, 'Nextcloud', $systemwebdavclient); 89 90 } 91 92 /** 93 * Function to test the private function create_share_user_sysaccount. 94 */ 95 public function test_create_share_user_sysaccount_user_shares() { 96 $params = [ 97 'path' => "/ambient.txt", 98 'shareType' => \repository_nextcloud\ocs_client::SHARE_TYPE_USER, 99 'publicUpload' => false, 100 'shareWith' => $this->systemaccountusername, 101 'permissions' => \repository_nextcloud\ocs_client::SHARE_PERMISSION_READ, 102 ]; 103 $expectedresponse = <<<XML 104 <?xml version="1.0"?> 105 <ocs> 106 <meta> 107 <status>ok</status> 108 <statuscode>100</statuscode> 109 <message/> 110 </meta> 111 <data> 112 <id>207</id> 113 <share_type>0</share_type> 114 <uid_owner>user1</uid_owner> 115 <displayname_owner>user1</displayname_owner> 116 <permissions>19</permissions> 117 <stime>1511532198</stime> 118 <parent/> 119 <expiration/> 120 <token/> 121 <uid_file_owner>user1</uid_file_owner> 122 <displayname_file_owner>user1</displayname_file_owner> 123 <path>/ambient.txt</path> 124 <item_type>file</item_type> 125 <mimetype>text/plain</mimetype> 126 <storage_id>home::user1</storage_id> 127 <storage>3</storage> 128 <item_source>545</item_source> 129 <file_source>545</file_source> 130 <file_parent>20</file_parent> 131 <file_target>/ambient.txt</file_target> 132 <share_with>tech</share_with> 133 <share_with_displayname>tech</share_with_displayname> 134 <mail_send>0</mail_send> 135 </data> 136 </ocs> 137 XML; 138 $this->ocsmockclient->expects($this->once())->method('call')->with('create_share', $params)->will( 139 $this->returnValue($expectedresponse)); 140 141 $result = $this->linkmanager->create_share_user_sysaccount("/ambient.txt"); 142 $xml = simplexml_load_string($expectedresponse); 143 $expected = array(); 144 $expected['statuscode'] = (int)$xml->meta->statuscode; 145 $expected['shareid'] = (int)$xml->data->id; 146 $expected['filetarget'] = (string)$xml->data[0]->file_target; 147 $this->assertEquals($expected, $result); 148 } 149 /** 150 * Test the delete_share_function. In case the request fails, the function throws an exception, however this 151 * can not be tested in phpUnit since it is javascript. 152 */ 153 public function test_delete_share_dataowner_sysaccount() { 154 $shareid = 5; 155 $deleteshareparams = [ 156 'share_id' => $shareid 157 ]; 158 $returnxml = <<<XML 159 <?xml version="1.0"?> 160 <ocs> 161 <meta> 162 <status>ok</status> 163 <statuscode>100</statuscode> 164 <message/> 165 </meta> 166 <data/> 167 </ocs> 168 XML; 169 $this->ocsmockclient->expects($this->once())->method('call')->with('delete_share', $deleteshareparams)->will( 170 $this->returnValue($returnxml)); 171 $this->linkmanager->delete_share_dataowner_sysaccount($shareid, 'repository_nextcloud'); 172 173 } 174 175 /** 176 * Function which test that create folder path does return the adequate results (path and success). 177 * Additionally mock checks whether the right params are passed to the corresponding functions. 178 */ 179 public function test_create_folder_path_folders_are_not_created() { 180 181 $mocks = $this->set_up_mocks_for_create_folder_path(true, 'somename'); 182 $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager); 183 $result = $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource", 184 'content', 0); 185 $this->assertEquals('/somename (ctx )/mod_resource/content/0', $result); 186 } 187 /** 188 * Function which test that create folder path does return the adequate results (path and success). 189 * Additionally mock checks whether the right params are passed to the corresponding functions. 190 */ 191 public function test_create_folder_path_folders_are_created() { 192 193 // In Context is okay, number of context counts for number of iterations. 194 $mocks = $this->set_up_mocks_for_create_folder_path(false, 'somename/withslash', true, 201); 195 $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager); 196 $result = $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource", 197 'content', 0); 198 $this->assertEquals('/somenamewithslash (ctx )/mod_resource/content/0', $result); 199 } 200 /** 201 * Test whether the create_folder_path methode throws exception. 202 */ 203 public function test_create_folder_path_folder_creation_fails() { 204 205 $mocks = $this->set_up_mocks_for_create_folder_path(false, 'somename', true, 400); 206 $this->set_private_property($mocks['mockclient'], 'systemwebdavclient', $this->linkmanager); 207 $this->expectException(\repository_nextcloud\request_exception::class); 208 $this->linkmanager->create_folder_path_access_controlled_links($mocks['mockcontext'], "mod_resource", 209 'content', 0); 210 } 211 212 /** 213 * Helper function to generate mocks for testing create folder path. 214 * @param bool $returnisdir Return value mocking the result of invoking is_dir 215 * @param bool $returnestedcontext Name of the folder that is simulated to be checked/created 216 * @param bool $callmkcol Also mock creation of the folder 217 * @param int $returnmkcol Return value mocking the result of invoking mkcol 218 * @return array ['mockcontext' context_module mock, 'mockclient' => webdav client mock] 219 */ 220 protected function set_up_mocks_for_create_folder_path($returnisdir, $returnestedcontext, $callmkcol = false, 221 $returnmkcol = 201) { 222 $mockcontext = $this->createMock(\context_module::class); 223 $mockclient = $this->getMockBuilder(\webdav_client::class 224 )->disableOriginalConstructor()->disableOriginalClone()->getMock(); 225 $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav')); 226 $webdavprefix = $parsedwebdavurl['path']; 227 // Empty ctx 'id' expected because using code will not be able to access $ctx->id. 228 $cleanedcontextname = clean_param($returnestedcontext, PARAM_FILE); 229 $dirstring = $webdavprefix . '/' . $cleanedcontextname . ' (ctx )'; 230 $mockclient->expects($this->atMost(4))->method('is_dir')->with($this->logicalOr( 231 $dirstring, $dirstring . '/mod_resource', $dirstring . '/mod_resource/content', 232 $dirstring . '/mod_resource/content/0'))->willReturn($returnisdir); 233 if ($callmkcol == true) { 234 $mockclient->expects($this->atMost(4))->method('mkcol')->willReturn($returnmkcol); 235 } 236 $mockcontext->method('get_parent_contexts')->willReturn(array('1' => $mockcontext)); 237 $mockcontext->method('get_context_name')->willReturn($returnestedcontext); 238 239 return array('mockcontext' => $mockcontext, 'mockclient' => $mockclient); 240 } 241 242 /** 243 * Test whether the right methods from the webdavclient are called when the storage_folder is created. 244 * 1. Directory already exist -> no further action needed. 245 */ 246 public function test_create_storage_folder_success() { 247 $mockwebdavclient = $this->createMock(\webdav_client::class); 248 $url = $this->issuer->get_endpoint_url('webdav'); 249 $parsedwebdavurl = parse_url($url); 250 $webdavprefix = $parsedwebdavurl['path']; 251 $mockwebdavclient->expects($this->once())->method('open')->willReturn(true); 252 $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(true); 253 $mockwebdavclient->expects($this->once())->method('close'); 254 $this->linkmanager->create_storage_folder('myname', $mockwebdavclient); 255 256 } 257 /** 258 * Test whether the right methods from the webdavclient are called when the storage_folder is created. 259 * 2. Directory does not exist. It is created with mkcol and returns a success. 260 * 261 */ 262 public function test_create_storage_folder_success_mkcol() { 263 $mockwebdavclient = $this->createMock(\webdav_client::class); 264 $url = $this->issuer->get_endpoint_url('webdav'); 265 $parsedwebdavurl = parse_url($url); 266 $webdavprefix = $parsedwebdavurl['path']; 267 $mockwebdavclient->expects($this->once())->method('open')->willReturn(true); 268 $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(false); 269 $mockwebdavclient->expects($this->once())->method('mkcol')->with($webdavprefix . 'myname')->willReturn(201); 270 $mockwebdavclient->expects($this->once())->method('close'); 271 272 $this->linkmanager->create_storage_folder('myname', $mockwebdavclient); 273 } 274 /** 275 * Test whether the right methods from the webdavclient are called when the storage_folder is created. 276 * 3. Request to create Folder fails. 277 */ 278 public function test_create_storage_folder_failure() { 279 $mockwebdavclient = $this->createMock(\webdav_client::class); 280 $url = $this->issuer->get_endpoint_url('webdav'); 281 $parsedwebdavurl = parse_url($url); 282 $webdavprefix = $parsedwebdavurl['path']; 283 $mockwebdavclient->expects($this->once())->method('open')->willReturn(true); 284 $mockwebdavclient->expects($this->once())->method('is_dir')->with($webdavprefix . 'myname')->willReturn(false); 285 $mockwebdavclient->expects($this->once())->method('mkcol')->with($webdavprefix . 'myname')->willReturn(400); 286 287 $this->expectException(\repository_nextcloud\request_exception::class); 288 $this->linkmanager->create_storage_folder('myname', $mockwebdavclient); 289 } 290 /** 291 * Test whether the webdav client gets the right params and whether function differentiates between move and copy. 292 */ 293 public function test_transfer_file_to_path_copyfile() { 294 // Initialize params. 295 $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav')); 296 $webdavprefix = $parsedwebdavurl['path']; 297 $srcpath = 'sourcepath'; 298 $dstpath = "destinationpath/another/path"; 299 300 // Mock the Webdavclient and set expected methods. 301 $systemwebdavclientmock = $this->createMock(\webdav_client::class); 302 $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true); 303 $systemwebdavclientmock->expects($this->once())->method('copy_file')->with($webdavprefix . $srcpath, 304 $webdavprefix . $dstpath . '/' . $srcpath, true)->willReturn(201); 305 $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager); 306 307 // Call of function. 308 $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'copy'); 309 310 $this->assertEquals(201, $result); 311 } 312 /** 313 * Test whether the webdav client gets the right params and whether function handles overwrite. 314 * 315 * @covers \repository_nextcloud\access_controlled_link_manager::transfer_file_to_path 316 */ 317 public function test_transfer_file_to_path_overwritefile() { 318 // Initialize params. 319 $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav')); 320 $webdavprefix = $parsedwebdavurl['path']; 321 $srcpath = 'sourcepath'; 322 $dstpath = "destinationpath/another/path"; 323 324 // Mock the Webdavclient and set expected methods. 325 $systemwebdavclientmock = $this->createMock(\webdav_client::class); 326 $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true); 327 $systemwebdavclientmock->expects($this->once())->method('copy_file')->with($webdavprefix . $srcpath, 328 $webdavprefix . $dstpath . '/' . $srcpath, true)->willReturn(204); 329 $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager); 330 331 // Call of function. 332 $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'copy'); 333 334 $this->assertEquals(204, $result); 335 } 336 /** 337 * This function tests whether the function transfer_file_to_path() moves or copies a given file to a given path 338 * It tests whether the webdav_client gets the right parameter and whether function distinguishes between move and copy. 339 * 340 */ 341 public function test_transfer_file_to_path_copyfile_movefile() { 342 // Initialize params. 343 $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav')); 344 $webdavprefix = $parsedwebdavurl['path']; 345 $srcpath = 'sourcepath'; 346 $dstpath = "destinationpath/another/path"; 347 348 $systemwebdavclientmock = $this->createMock(\webdav_client::class); 349 350 $systemwebdavclientmock->expects($this->once())->method('open')->willReturn(true); 351 $this->set_private_property($systemwebdavclientmock, 'systemwebdavclient', $this->linkmanager); 352 $webdavclientmock = $this->createMock(\webdav_client::class); 353 354 $webdavclientmock->expects($this->once())->method('move')->with($webdavprefix . $srcpath, 355 $webdavprefix . $dstpath . '/' . $srcpath, false)->willReturn(201); 356 $result = $this->linkmanager->transfer_file_to_path($srcpath, $dstpath, 'move', $webdavclientmock); 357 $this->assertEquals(201, $result); 358 } 359 360 /** 361 * Test the get_shares_from path() function. This function extracts from an list of shares the share of a given user 362 * (the username is a parameter in the function call) and returns the id. The test firstly test whether the right fileid 363 * for user1 is extracted then for user2 and last but least whether an error is thrown if the user does not have a share. 364 * @throws moodle_exception 365 */ 366 public function test_get_shares_from_path() { 367 $params = [ 368 'path' => '/Kernsystem/Kursbereich Miscellaneous/Kurs Example Course/Datei zet/mod_resource/content/0/picture.png', 369 'reshares' => true 370 ]; 371 $reference = new \stdClass(); 372 $reference->link = "/Kernsystem/Kursbereich Miscellaneous/Kurs Example Course/Datei zet/mod_resource/content/0/picture.png"; 373 $reference->name = "f\u00fcrdennis.png"; 374 $reference->usesystem = true; 375 $expectedresponse = <<<XML 376 <?xml version="1.0"?> 377 <ocs> 378 <meta> 379 <status>ok</status> 380 <statuscode>100</statuscode> 381 <message/> 382 </meta> 383 <data> 384 <element> 385 <id>292</id> 386 <share_type>0</share_type> 387 <uid_owner>tech</uid_owner> 388 <displayname_owner>tech</displayname_owner> 389 <permissions>19</permissions> 390 <stime>1515752494</stime> 391 <parent/> 392 <expiration/> 393 <token/> 394 <uid_file_owner>tech</uid_file_owner> 395 <displayname_file_owner>tech</displayname_file_owner> 396 <path>some/path/of/some/file.pdf</path> 397 <item_type>file</item_type> 398 <mimetype>image/png</mimetype> 399 <storage_id>home::tech</storage_id> 400 <storage>4</storage> 401 <item_source>1085</item_source> 402 <file_source>1085</file_source> 403 <file_parent>1084</file_parent> 404 <file_target>/fehler (3).png</file_target> 405 <share_with>user1</share_with> 406 <share_with_displayname>user1</share_with_displayname> 407 <mail_send>0</mail_send> 408 </element> 409 <element> 410 <id>293</id> 411 <share_type>0</share_type> 412 <uid_owner>tech</uid_owner> 413 <displayname_owner>tech</displayname_owner> 414 <permissions>19</permissions> 415 <stime>1515752494</stime> 416 <parent/> 417 <expiration/> 418 <token/> 419 <uid_file_owner>tech</uid_file_owner> 420 <displayname_file_owner>tech</displayname_file_owner> 421 <path>some/path/of/some/file.pdf</path> 422 <item_type>file</item_type> 423 <mimetype>image/png</mimetype> 424 <storage_id>home::tech</storage_id> 425 <storage>4</storage> 426 <item_source>1085</item_source> 427 <file_source>1085</file_source> 428 <file_parent>1084</file_parent> 429 <file_target>/fehler (3).png</file_target> 430 <share_with>user2</share_with> 431 <share_with_displayname>user2</share_with_displayname> 432 <mail_send>0</mail_send> 433 </element> 434 </data> 435 </ocs> 436 XML; 437 $this->set_private_property($this->ocsmockclient, 'systemocsclient', $this->linkmanager); 438 439 $this->ocsmockclient->expects($this->exactly(3))->method('call')->with('get_shares', $params)->will( 440 $this->returnValue($expectedresponse)); 441 $xmlobjuser1 = (int) $this->linkmanager->get_shares_from_path($reference->link, 'user2'); 442 $xmlobjuser2 = (int) $this->linkmanager->get_shares_from_path($reference->link, 'user1'); 443 444 $this->assertEquals(293, $xmlobjuser1); 445 $this->assertEquals(292, $xmlobjuser2); 446 447 $this->expectException(\repository_nextcloud\request_exception::class); 448 449 $this->expectExceptionMessage('A request to Nextcloud has failed. The requested file could not be accessed. Please ' . 450 'check whether you have chosen a valid file and you are authenticated with the right account.'); 451 $this->linkmanager->get_shares_from_path($reference->link, 'user3'); 452 453 } 454 /** Test whether the systemwebdav client is constructed correctly. Port is set to 443 in case of https, to 80 in 455 * case of http and exception is thrown when endpoint does not exist. 456 * @throws \repository_nextcloud\configuration_exception 457 * @throws coding_exception 458 */ 459 public function test_create_system_dav() { 460 // Initialize mock and params. 461 $fakeaccesstoken = new \stdClass(); 462 $fakeaccesstoken->token = "fake access token"; 463 // Use `atLeastOnce` instead of `exactly(2)` because it is only called a second time on dev systems that allow http://. 464 $this->oauthsystemmock->expects($this->atLeastOnce())->method('get_accesstoken')->willReturn($fakeaccesstoken); 465 $parsedwebdavurl = parse_url($this->issuer->get_endpoint_url('webdav')); 466 467 // Call function and create own client. 468 $dav = $this->linkmanager->create_system_dav(); 469 $mydav = new \webdav_client($parsedwebdavurl['host'], '', '', 'bearer', 'ssl://', 470 "fake access token", $parsedwebdavurl['path']); 471 $mydav->port = 443; 472 $mydav->debug = false; 473 $this->assertEquals($mydav, $dav); 474 475 // Deletes the old webdav endpoint and ... 476 $this->delete_endpoints('webdav_endpoint'); 477 // Creates a new one which requires different ports. 478 try { 479 $endpoint = new \stdClass(); 480 $endpoint->name = "webdav_endpoint"; 481 $endpoint->url = 'http://www.default.test/webdav/index.php'; 482 $endpoint->issuerid = $this->issuer->get('id'); 483 \core\oauth2\api::create_endpoint($endpoint); 484 485 // Call function and create own client. 486 $dav = $this->linkmanager->create_system_dav(); 487 $mydav = new \webdav_client($parsedwebdavurl['host'], '', '', 'bearer', '', 488 "fake access token"); 489 $mydav->port = 80; 490 $mydav->debug = false; 491 $this->assertEquals($mydav, $dav); 492 } catch (core\invalid_persistent_exception $e) { 493 // In some cases Moodle does not allow to create http connections. In those cases the exception 494 // is catched here and the test are executed. 495 $this->expectException(\core\invalid_persistent_exception::class); 496 $this->linkmanager->create_system_dav(); 497 } finally { 498 499 // Delte endpoints and ... 500 $this->delete_endpoints('webdav_endpoint'); 501 502 // Do not insert new ones, therefore exception is thrown. 503 $this->expectException(\repository_nextcloud\configuration_exception::class); 504 $this->linkmanager->create_system_dav(); 505 } 506 } 507 508 /** 509 * Tests the function get_share_information_from_shareid(). From a response with two element it is tested 510 * whether the right file_target is extracted and lastly it is checked whether an error is thrown in case no suitable 511 * element exists. 512 * @throws \repository_nextcloud\request_exception 513 * @throws coding_exception 514 */ 515 public function test_get_share_information_from_shareid() { 516 $params303 = [ 517 'share_id' => 303, 518 ]; 519 $params302 = [ 520 'share_id' => 302, 521 ]; 522 $expectedresponse = <<<XML 523 <?xml version="1.0"?> 524 <ocs> 525 <meta> 526 <status>ok</status> 527 <statuscode>100</statuscode> 528 <message/> 529 </meta> 530 <data> 531 <element> 532 <id>302</id> 533 <share_type>0</share_type> 534 <uid_owner>tech</uid_owner> 535 <displayname_owner>tech</displayname_owner> 536 <permissions>19</permissions> 537 <stime>1516096325</stime> 538 <parent/> 539 <expiration/> 540 <token/> 541 <uid_file_owner>tech</uid_file_owner> 542 <displayname_file_owner>tech</displayname_file_owner> 543 <path>/some/target (2).png</path> 544 <item_type>file</item_type> 545 <mimetype>image/png</mimetype> 546 <storage_id>shared::/some/target.png</storage_id> 547 <storage>4</storage> 548 <item_source>1125</item_source> 549 <file_source>1125</file_source> 550 <file_parent>20</file_parent> 551 <file_target>/some/target.png</file_target> 552 <share_with>user1</share_with> 553 <share_with_displayname>user1</share_with_displayname> 554 <mail_send>0</mail_send> 555 </element> 556 <element> 557 <id>303</id> 558 <share_type>0</share_type> 559 <uid_owner>tech</uid_owner> 560 <displayname_owner>tech</displayname_owner> 561 <permissions>19</permissions> 562 <stime>1516096325</stime> 563 <parent/> 564 <expiration/> 565 <token/> 566 <uid_file_owner>tech</uid_file_owner> 567 <displayname_file_owner>tech</displayname_file_owner> 568 <path>/some/target (2).pdf</path> 569 <item_type>file</item_type> 570 <mimetype>image/png</mimetype> 571 <storage_id>shared::/some/target.pdf</storage_id> 572 <storage>4</storage> 573 <item_source>1125</item_source> 574 <file_source>1125</file_source> 575 <file_parent>20</file_parent> 576 <file_target>/some/target.pdf</file_target> 577 <share_with>user2</share_with> 578 <share_with_displayname>user1</share_with_displayname> 579 <mail_send>0</mail_send> 580 </element> 581 </data> 582 </ocs> 583 XML; 584 $this->set_private_property($this->ocsmockclient, 'systemocsclient', $this->linkmanager); 585 586 $this->ocsmockclient->expects($this->exactly(3))->method('call')->with('get_information_of_share', 587 $this->logicalOr($params303, $params302))->will($this->returnValue($expectedresponse)); 588 589 // Test function for two different users. Setting the id is just a dummy value since always $expectedresponse ... 590 // ... is returned. 591 $filetarget = $this->linkmanager->get_share_information_from_shareid(303, 'user2'); 592 $this->assertEquals('/some/target.pdf', $filetarget); 593 594 $filetarget = $this->linkmanager->get_share_information_from_shareid(302, 'user1'); 595 $this->assertEquals('/some/target.png', $filetarget); 596 597 // Expect exception in case no suitable elemtn exist in the response. 598 $this->expectException(\repository_nextcloud\request_exception::class); 599 $this->expectExceptionMessage('A request to Nextcloud has failed. The requested file could not be accessed. Please ' . 600 'check whether you have chosen a valid file and you are authenticated with the right account.'); 601 $this->linkmanager->get_share_information_from_shareid(302, 'user3'); 602 } 603 604 /** 605 * Helper method which inserts a value into a non-public field of an object. 606 * 607 * @param mixed $value mock value that will be inserted. 608 * @param string $propertyname name of the private property. 609 * @param object $class Instance that is being modified. 610 * @return ReflectionProperty the resulting reflection property. 611 */ 612 protected function set_private_property($value, $propertyname, $class) { 613 $refclient = new \ReflectionClass($class); 614 $private = $refclient->getProperty($propertyname); 615 $private->setAccessible(true); 616 $private->setValue($class, $value); 617 return $private; 618 } 619 /** 620 * Helper method which gets a value from a non-public field of an object. 621 * 622 * @param string $propertyname name of the private property. 623 * @param object $class Instance that is being modified. 624 * @return mixed the resulting value. 625 */ 626 protected function get_private_property($propertyname, $class) { 627 $refclient = new \ReflectionClass($class); 628 $private = $refclient->getProperty($propertyname); 629 $private->setAccessible(true); 630 $property = $private->getValue($private); 631 return $property; 632 } 633 /** 634 * Deletes all endpoint with the given name. 635 * @param string $endpointname 636 * @return array|null 637 * @throws moodle_exception 638 */ 639 protected function delete_endpoints($endpointname) { 640 $endpoints = \core\oauth2\api::get_endpoints($this->issuer); 641 $arrayofids = array(); 642 foreach ($endpoints as $endpoint) { 643 $name = $endpoint->get('name'); 644 if ($name === $endpointname) { 645 $arrayofids[$endpoint->get('id')] = $endpoint->get('id'); 646 } 647 } 648 if (empty($arrayofids)) { 649 return; 650 } 651 foreach ($arrayofids as $id) { 652 \core\oauth2\api::delete_endpoint($id); 653 } 654 } 655 656 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body