1<?php
2
3namespace dokuwiki\test\Action;
4
5use dokuwiki\Action\AbstractAclAction;
6use dokuwiki\Action\AbstractUserAction;
7use dokuwiki\Action\Exception\ActionAclRequiredException;
8use dokuwiki\Action\Exception\ActionDisabledException;
9use dokuwiki\Action\Exception\ActionUserRequiredException;
10
11class ActionTest extends \DokuWikiTest
12{
13
14    public function dataProvider()
15    {
16        return array(
17            array('Login', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
18            array('Logout', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
19            array('Search', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
20            array('Recent', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
21            array('Profile', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
22            array('ProfileDelete', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
23            array('Index', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
24            array('Sitemap', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
25            array('Denied', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
26            array('Register', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
27            array('Resendpwd', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
28            array('Backlink', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
29
30            array('Revert', AUTH_EDIT, array('exists' => true, 'ismanager' => false)),
31            array('Revert', AUTH_EDIT, array('exists' => true, 'ismanager' => true)),
32
33            array('Admin', AUTH_READ, array('exists' => true, 'ismanager' => false)), // let in, check later again
34            array('Admin', AUTH_READ, array('exists' => true, 'ismanager' => true)), // let in, check later again
35
36            array('Check', AUTH_READ, array('exists' => true, 'ismanager' => false)), // sensible?
37            array('Diff', AUTH_READ, array('exists' => true, 'ismanager' => false)),
38            array('Show', AUTH_READ, array('exists' => true, 'ismanager' => false)),
39            array('Subscribe', AUTH_READ, array('exists' => true, 'ismanager' => false)),
40            array('Locked', AUTH_READ, array('exists' => true, 'ismanager' => false)),
41            array('Source', AUTH_READ, array('exists' => true, 'ismanager' => false)),
42            array('Export', AUTH_READ, array('exists' => true, 'ismanager' => false)),
43            array('Media', AUTH_READ, array('exists' => true, 'ismanager' => false)),
44            array('Revisions', AUTH_READ, array('exists' => true, 'ismanager' => false)),
45
46            array('Draftdel', AUTH_EDIT, array('exists' => true, 'ismanager' => false)),
47
48            // aliases
49            array('Cancel', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
50            array('Recover', AUTH_NONE, array('exists' => true, 'ismanager' => false)),
51
52            // EDITING existing page
53            array('Save', AUTH_EDIT, array('exists' => true, 'ismanager' => false)),
54            array('Conflict', AUTH_EDIT, array('exists' => true, 'ismanager' => false)),
55            array('Draft', AUTH_EDIT, array('exists' => true, 'ismanager' => false)),
56            //the edit function will check again and do a source show
57            //when no AUTH_EDIT available:
58            array('Edit', AUTH_READ, array('exists' => true, 'ismanager' => false)),
59            array('Preview', AUTH_READ, array('exists' => true, 'ismanager' => false)),
60
61            // EDITING new page
62            array('Save', AUTH_CREATE, array('exists' => false, 'ismanager' => false)),
63            array('Conflict', AUTH_CREATE, array('exists' => false, 'ismanager' => false)),
64            array('Draft', AUTH_CREATE, array('exists' => false, 'ismanager' => false)),
65            array('Edit', AUTH_CREATE, array('exists' => false, 'ismanager' => false)),
66            array('Preview', AUTH_CREATE, array('exists' => false, 'ismanager' => false)),
67        );
68    }
69
70    /**
71     * @dataProvider dataProvider
72     * @param $name
73     * @param $expected
74     * @param $info
75     */
76    public function testMinimumPermissions($name, $expected, $info)
77    {
78        global $INFO;
79        $INFO = $info;
80
81        $classname = 'dokuwiki\\Action\\' . $name;
82        /** @var \dokuwiki\Action\AbstractAction $class */
83        $class = new $classname();
84
85        $this->assertSame($expected, $class->minimumPermission());
86    }
87
88    /**
89     * All actions should handle the disableactions setting
90     *
91     * @dataProvider dataProvider
92     * @param $name
93     */
94    public function testBaseClassActionOkPermission($name)
95    {
96        $this->assertTrue(true); // mark as not risky
97        if ($name == 'Show') return; // disabling show does not work
98
99        $classname = 'dokuwiki\\Action\\' . $name;
100        /** @var \dokuwiki\Action\AbstractAction $class */
101        $class = new $classname();
102
103        global $conf;
104        $conf['useacl'] = 1;
105        $conf['subscribers'] = 1;
106        $conf['disableactions'] = '';
107        $_SERVER['REMOTE_USER'] = 'someone';
108
109        try {
110            \dokuwiki\ActionRouter::getInstance(true)->checkAction($class);
111        } catch (\Exception $e) {
112            $this->assertNotSame(ActionDisabledException::class, get_class($e));
113        }
114
115        $conf['disableactions'] = $class->getActionName();
116
117        try {
118            \dokuwiki\ActionRouter::getInstance(true)->checkAction($class);
119        } catch (\Exception $e) {
120            $this->assertSame(ActionDisabledException::class, get_class($e), $e);
121        }
122    }
123
124    /**
125     * Actions inheriting from AbstractAclAction should have an ACL enabled check
126     *
127     * @dataProvider dataProvider
128     * @param $name
129     */
130    public function testBaseClassAclPermission($name)
131    {
132        $classname = 'dokuwiki\\Action\\' . $name;
133        /** @var \dokuwiki\Action\AbstractAction $class */
134        $class = new $classname();
135        $this->assertTrue(true); // mark as not risky
136        if (!is_a($class, AbstractAclAction::class)) return;
137
138        global $conf;
139        $conf['useacl'] = 1;
140        $conf['subscribers'] = 1;
141
142        try {
143            $class->checkPreconditions();
144        } catch (\Exception $e) {
145            $this->assertNotSame(ActionAclRequiredException::class, get_class($e));
146        }
147
148        $conf['useacl'] = 0;
149
150        try {
151            $class->checkPreconditions();
152        } catch (\Exception $e) {
153            $this->assertSame(ActionAclRequiredException::class, get_class($e));
154        }
155    }
156
157    /**
158     * Actions inheriting from AbstractUserAction should have user check
159     *
160     * @dataProvider dataProvider
161     * @param $name
162     */
163    public function testBaseClassUserPermission($name)
164    {
165        $classname = 'dokuwiki\\Action\\' . $name;
166        /** @var \dokuwiki\Action\AbstractAction $class */
167        $class = new $classname();
168        $this->assertTrue(true); // mark as not risky
169        if (!is_a($class, AbstractUserAction::class)) return;
170
171        global $conf;
172        $conf['useacl'] = 1;
173        $conf['subscribers'] = 1;
174        $_SERVER['REMOTE_USER'] = 'test';
175
176        try {
177            $class->checkPreconditions();
178        } catch (\Exception $e) {
179            $this->assertNotSame(ActionUserRequiredException::class, get_class($e));
180        }
181
182        unset($_SERVER['REMOTE_USER']);
183
184        try {
185            $class->checkPreconditions();
186        } catch (\Exception $e) {
187            $this->assertSame(ActionUserRequiredException::class, get_class($e));
188        }
189    }
190}
191