1<?php
2
3/**
4 * Dokuwiki WebDAV Plugin: Admin Interface
5 *
6 * @link     https://dokuwiki.org/plugin:webdav
7 * @author   Giuseppe Di Terlizzi <giuseppe.diterlizzi@gmail.com>
8 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
9 */
10
11require_once DOKU_PLUGIN . 'webdav/vendor/autoload.php';
12
13use Sabre\DAV\Locks\LockInfo;
14
15class admin_plugin_webdav extends DokuWiki_Admin_Plugin
16{
17    /** @inheritDoc */
18    public function getMenuSort()
19    {
20        return 1;
21    }
22
23    /** @inheritDoc */
24    public function forAdminOnly()
25    {
26        return false;
27    }
28
29    /** @inheritDoc */
30    public function getMenuIcon()
31    {
32        return dirname(__FILE__) . '/folder-network-outline.svg';
33    }
34
35    /** @inheritDoc */
36    public function getMenuText($language)
37    {
38        return 'WebDAV';
39    }
40
41    /** @inheritDoc */
42    public function handle()
43    {
44        global $INPUT;
45
46        if (!$_REQUEST['cmd']) {
47            return;
48        }
49
50        if (!checkSecurityToken()) {
51            return;
52        }
53
54        $cmd = $INPUT->extract('cmd')->str('cmd');
55
56        $dispatch = [
57            'unlock' => 'unlockFile',
58        ];
59
60        if ($cmd) {
61            if (!isset($dispatch[$cmd])) {
62                msg('Unknown command', -1);
63                return;
64            }
65            call_user_func([$this, $dispatch[$cmd]]);
66        }
67    }
68
69    /**
70     * Unlock file
71     *
72     * @return bool
73     */
74    public function unlockFile()
75    {
76        global $INPUT;
77        global $conf;
78
79        $lock_id     = $INPUT->str('lock');
80        $locks_file  = $conf['cachedir'] . '/webdav.lock';
81        $locked_file = '';
82
83        if (!$lock_id) {
84            msg('No lock provided', -1);
85            return;
86        }
87
88        if ($locks = $this->getLocks()) {
89            foreach ($locks as $id => $lock) {
90                if ($lock->token == $lock_id) {
91                    $locked_file = $lock->uri;
92                    unset($locks[$id]);
93                }
94            }
95
96            if ($locked_file) {
97                if (!io_saveFile($locks_file, serialize($locks))) {
98                    msg('Unlock failed', -1);
99                    return;
100                }
101
102                msg("File $locked_file successfully unlocked", 1);
103            }
104        }
105    }
106
107    /** @inheritDoc */
108    public function html()
109    {
110        echo '<div id="plugin_advanced_export">';
111        echo $this->locale_xhtml('intro');
112
113        echo '<form action="" method="post" class="form-inline">';
114
115        $this->displayLocks();
116
117        formSecurityToken();
118
119        echo '<input type="hidden" name="do" value="admin" />';
120        echo '<input type="hidden" name="page" value="webdav" />';
121        echo '<input type="hidden" name="cmd" value="unlock" />';
122
123        echo '</form>';
124        echo '</div>';
125    }
126
127    /**
128     * Display active locks
129     */
130    private function displayLocks()
131    {
132        echo '<h3>Locks</h3>';
133        echo '<table class="inline" style="width:100%">';
134        echo '<thead>
135            <tr>
136                <th>Owner</th>
137                <th>Timeout</th>
138                <th>Created</th>
139                <th>Type</th>
140                <th>URI</th>
141                <th>User Agent</th>
142                <th>&nbsp;</th>
143            </tr>
144        </thead>';
145        echo '<tbody>';
146        foreach ($this->getLocks() as $lock) {
147            $pathinfo = pathinfo($lock->uri);
148            echo '<tr>';
149            echo '<td><a href="#" class="interwiki iw_user"></a>' . (($lock->owner == $lock->user) ? $lock->owner : $lock->user . ' (' . $lock->owner . ')') . '</td>';
150            echo "<td>{$lock->timeout} seconds</td>";
151            echo '<td>' . datetime_h($lock->created) . '<br><small>(' . dformat($lock->created) . ')</small></td>';
152            echo "<td>{$this->getLockType($lock->scope)}</td>";
153            echo '<td><a class="mediafile mf_' . $pathinfo['extension'] . '" href="' . getBaseURL(true) . 'lib/plugins/webdav/server.php/' . hsc($lock->uri) . '">' . $lock->uri . '</a></td>';
154            echo "<td>{$lock->ua}</td>";
155            echo '<td><button type="submit" class="btn btn-default btn-xs btn_unlock_file" name="lock" value="' . $lock->token . '">Unlock</button></td>';
156            echo '</tr>';
157        }
158        echo '</tbody>';
159        echo '</table>';
160    }
161
162    /**
163     * Get active locks
164     *
165     * @return array
166     */
167    private function getLocks()
168    {
169        global $conf;
170
171        $locks      = [];
172        $locks_file = $conf['cachedir'] . '/webdav.lock';
173
174        if (file_exists($locks_file)) {
175            $locks = unserialize(io_readFile($locks_file));
176        }
177        return $locks;
178    }
179
180    /**
181     * Get lock type
182     *
183     * @param string $scope
184     * @return string
185     */
186    private function getLockType($scope)
187    {
188        switch ($scope) {
189            case LockInfo::EXCLUSIVE:
190                return 'Exclusive';
191            case LockInfo::SHARED:
192                return 'Shared';
193            case LockInfo::TIMEOUT_INFINITE:
194                return 'Timeout Infinite';
195            default:
196                return 'N/A';
197        }
198    }
199}
200