1<?php 2 3/** 4 * Tests for the ACL enforcement of media_restore(). 5 * 6 * The restore target is a request parameter independent of the namespace the 7 * media manager derived its authorization from, so media_restore() must 8 * authorize the target media id itself rather than trusting the passed value. 9 */ 10class media_restore_test extends DokuWikiTest { 11 12 public function setUp(): void { 13 parent::setUp(); 14 15 global $conf, $AUTH_ACL, $USERINFO; 16 17 $conf['useacl'] = 1; 18 $conf['mediarevisions'] = 1; 19 $_SERVER['REMOTE_USER'] = 'john'; 20 $USERINFO['grps'] = ['user']; 21 22 // upload allowed in public:*, but denied in the child public:private:* 23 $AUTH_ACL = [ 24 '* @ALL 0', 25 'public:* @user 8', // AUTH_UPLOAD 26 'public:private:* @user 0', // AUTH_NONE 27 ]; 28 } 29 30 /** 31 * Create a current media file and one old revision of it. 32 * 33 * @param string $id media id 34 * @param int $rev revision timestamp 35 * @param string $current content of the current file 36 * @param string $old content of the stored revision 37 */ 38 protected function seedRevision($id, $rev, $current, $old) { 39 $cur = mediaFN($id); 40 io_makeFileDir($cur); 41 file_put_contents($cur, $current); 42 43 $att = mediaFN($id, $rev); 44 io_makeFileDir($att); 45 file_put_contents($att, $old); 46 } 47 48 /** 49 * Restoring a revision of a media file in an ACL-denied namespace must be 50 * rejected, even when the request is otherwise valid. 51 */ 52 public function test_restore_rejects_denied_namespace() { 53 $id = 'public:private:secret.png'; 54 $rev = 1000000000; 55 $this->seedRevision($id, $rev, 'CURRENT', 'OLD'); 56 57 $res = media_restore($id, $rev); 58 59 $this->assertFalse($res); 60 $this->assertSame('CURRENT', file_get_contents(mediaFN($id)), 'protected file must be untouched'); 61 } 62 63 /** 64 * Restoring a revision in a permitted namespace must overwrite the current 65 * file with the stored revision. 66 */ 67 public function test_restore_allows_permitted_namespace() { 68 $id = 'public:target.png'; 69 $rev = 1000000000; 70 $this->seedRevision($id, $rev, 'CURRENT', 'OLD'); 71 72 $res = media_restore($id, $rev); 73 74 $this->assertSame($id, $res); 75 $this->assertSame('OLD', file_get_contents(mediaFN($id)), 'current file must hold the restored revision'); 76 } 77} 78