Completed
Pull Request — master (#176)
by Stefan
02:09
created

DBConnector::checkPermission()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 8
nc 2
nop 0
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php namespace palma;
2
3
// Copyright (C) 2014 Universitätsbibliothek Mannheim
4
// See file LICENSE for license details.
5
6
// Authors: Alexander Wagner, Stefan Weil
7
8
require_once('globals.php');
9
10
class DBConnector extends \SQLite3
11
{
12
    const SQL_CREATE_TABLES = <<< eod
13
14
PRAGMA foreign_keys = ON;
15
16
CREATE TABLE IF NOT EXISTS setting (
17
  key VARCHAR (10) PRIMARY KEY,
18
  value VARCHAR (20)
19
);
20
INSERT OR IGNORE INTO setting VALUES ('layout', 'g1x1');
21
INSERT OR IGNORE INTO setting VALUES ('pin', '');
22
23
CREATE TABLE IF NOT EXISTS user (
24
  userid INTEGER PRIMARY KEY,
25
  name VARCHAR (30) UNIQUE,
26
  count INTEGER,
27
  enabled INTEGER
28
);
29
30
-- Table with user name, IP address and device type (laptop, tablet, mobile).
31
CREATE TABLE IF NOT EXISTS address (
32
  userid INTEGER,
33
  address VARCHAR (30),
34
  device VARCHAR (6),
35
  FOREIGN KEY(userid) REFERENCES user(userid)
36
);
37
38
-- TODO: Entry 'userid' in table 'window' should refer to user(userid):
39
-- userid INTEGER REFERENCES user(userid)
40
-- The software currently does not handle this correctly, so we had to remove
41
-- the reference because it fails with pragma foreign_keys.
42
CREATE TABLE IF NOT EXISTS window (
43
  id INTEGER PRIMARY KEY,
44
  win_id VARCHAR (3),
45
  section INTEGER,
46
  state VARCHAR (10),
47
  file VARCHAR (255),
48
  handler VARCHAR (255),
49
  userid INTEGER,
50
  date DATETIME
51
);
52
eod;
53
54
    const SQL_RESET_TABLES = <<< eod
55
            DROP TABLE address;
56
            DROP TABLE setting;
57
            DROP TABLE IF EXISTS settings;
58
            DROP TABLE user;
59
            DROP TABLE window;
60
eod;
61
62
    // TODO: allow additional flags for constructor:
63
    // $flags = SQLITE3_OPEN_READWRITE|SQLITE3_OPEN_CREATE
64
    // $encryption_key
65
    public function __construct($filename = false)
66
    {
67
        if (!$filename) {
68
            $filename = 'palma.db';
69
        }
70
        trace("DBConnector db file = $filename");
71
        parent::__construct($filename);
72
73
        // Wait up to 10000 ms when the database is locked.
74
        $this->busyTimeout(10000);
75
76
        // Create any missing tables.
77
        $this->exec(self::SQL_CREATE_TABLES);
78
    }
79
80
    public function resetTables()
81
    {
82
        $this->exec(self::SQL_RESET_TABLES . self::SQL_CREATE_TABLES);
83
    }
84
85
    public function countWindows()
86
    {
87
        $numRows = $this->querySingle('SELECT count(*) FROM window WHERE state="active"');
88
        return $numRows;
89
    }
90
91
    public function nextID()
92
    {
93
        // Find the first unused monitor section and return its number.
94
        $quadrant_ids = array(1, 2, 3, 4);
95
        $window_db_ids = array();
96
97
        $window_keys = @$this->query('SELECT DISTINCT(id) FROM window');
98
        while ($row = $window_keys->fetchArray()) {
99
            array_push($window_db_ids, $row['id']);
100
        }
101
        $window_keys->finalize();
102
        //~ trace("ids in QD " . serialize($quadrant_ids));
103
        //~ trace("ids in DB " . serialize($window_db_ids));
104
105
        $next_ids = array_values(array_diff($quadrant_ids, $window_db_ids));
106
        //~ trace("ids in NXT " . serialize($next_ids));
107
        if (count($next_ids) > 0) {
108
            $next = $next_ids[0];
109
        } else {
110
            $next = $this->querySingle('SELECT MAX(id) FROM window') + 1;
111
        }
112
        return $next;
113
    }
114
115
    public function ipAddress()
116
    {
117
        $ip = 'unknown';
118
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
119
            // Server is hidden behind a proxy.
120
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
121
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
122
            // Client has direct access to the server.
123
            $ip = $_SERVER['REMOTE_ADDR'];
124
        }
125
        return $ip;
126
    }
127
128
    public function checkPermission()
129
    {
130
        $ip = $this->ipAddress();
131
        $ip_list = array();
132
        $rows = $this->query("SELECT address FROM address");
133
        while ($row = $rows->fetchArray(SQLITE3_ASSOC)) {
134
            array_push($ip_list, $row['address']);
135
        }
136
        $rows->finalize();
137
        $allowed = in_array($ip, $ip_list);
138
        return $allowed;
139
    }
140
141
    public function addUser($username, $address, $device = 'laptop')
142
    {
143
        // Add a new user with his/her address and the device to the database.
144
        // TODO: Support more than one address for a given username.
145
        $this->exec("INSERT OR IGNORE INTO user VALUES (NULL, '$username', 1, 0)");
146
        $usercount = $this->querySingle("SELECT COUNT(*) FROM user");
147
        $userid = $this->querySingle("SELECT userid from user where name='".$username."'");
148
        $this->exec("INSERT INTO address VALUES ('$userid', '$address', '$device')");
149
        trace("user $username connected with $device, $usercount user(s) now connected");
150
        if ($usercount == 1) {
151
            // First user connected. Always enable this person.
152
            $this->enableUser($username);
153
        }
154
    }
155
156
    public function delUser($username, $address)
0 ignored issues
show
Unused Code introduced by
The parameter $address is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

156
    public function delUser($username, /** @scrutinizer ignore-unused */ $address)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
157
    {
158
        // Remove an existing user with his/her address from the database.
159
        // TODO: Support more than one address for a given username.
160
        $ip = $this->ipAddress();
161
        $userid = $this->querySingle("SELECT userid from user where name='$username'");
162
        // Kill VNC connection associated with the user
163
        $this->deleteVNCWindow($userid);
164
        $this->exec("DELETE FROM address WHERE userid = '$userid' AND address = '$ip'");
165
        // TODO: Remove user only when no address refers to it.
166
        $this->exec("DELETE FROM user WHERE userid = '$userid'");
167
        $usercount = $this->querySingle("SELECT COUNT(*) FROM user");
168
        trace("user $username disconnected, $usercount user(s) now connected");
169
        if ($usercount == 0) {
170
            // Last user disconnected.
171
            // Clean some tables, just to be sure that nothing is left.
172
            $this->exec("DELETE FROM address; DELETE FROM window;");
173
        }
174
    }
175
176
    public function enableUser($username)
177
    {
178
        $state = $this->exec("UPDATE user SET enabled=1 WHERE name='$username'");
179
        if (!$state) {
180
            trace("enableUser($username) failed");
181
        }
182
    }
183
184
    public function getUsers()
185
    {
186
        $users = array();
187
        $rows = $this->query("SELECT name FROM user");
188
        while ($row = $rows->fetchArray(SQLITE3_ASSOC)) {
189
            array_push($users, $row['name']);
190
        }
191
        $rows->finalize();
192
        return $users;
193
    }
194
195
    public function getWindows()
196
    {
197
        // Get list of all windows, ordered by their section.
198
        $window_objs = array();
199
        $windows = @$this->query('SELECT * FROM window ORDER BY section ASC');
200
        while ($row = $windows->fetchArray()) {
201
            array_push($window_objs, $row);
202
        }
203
        $windows->finalize();
204
205
        return $window_objs;
206
    }
207
208
    public function getWindowIDBySection($section)
209
    {
210
        $id = $this->querySingle("SELECT win_id FROM window WHERE section='$section'");
211
        return $id;
212
    }
213
214
    public function getVNCClientInfo()
215
    {
216
217
        $info = array();
218
219
        $i = @$this->query('SELECT * FROM window WHERE handler="vnc"');
220
        while ($row = $i->fetchArray()) {
221
            array_push($info, $row);
222
        }
223
        $i->finalize();
224
225
        return $info;
226
    }
227
228
    /*
229
    public function getVNC_ClientWindowIDs() {
230
        $ids = array();
231
        $rows = @$this->query('SELECT win_id FROM window WHERE handler="vnc"');
232
        while ($row = $rows->fetchArray()) {
233
            array_push($ids, $row['win_id']);
234
        }
235
        $rows->finalize();
236
        return $ids;
237
    }
238
    */
239
240
    public function getWindowState($window_id)
241
    {
242
        $state = @$this->querySingle('SELECT state FROM window WHERE win_id="'.$window_id.'"');
243
        return $state;
244
    }
245
246
    public function setWindowState($window_id, $state)
247
    {
248
        $this->exec('UPDATE window SET state="'.$state.'" WHERE win_id="'.$window_id.'"');
249
    }
250
251
    public function insertWindow($window)
252
    {
253
        // transfer ob complete window object/array necessary
254
        $sql = 'INSERT INTO window (id, win_id, section, state, file, handler, userid, date) ' .
255
                'VALUES ' . '("' .
256
                $window[0] . '", "' . $window[1] . '", "' .
257
                $window[2] . '", "' . $window[3] . '", "' .
258
                $window[4] . '", "' . $window[5] . '", "' .
259
                $window[6] . '", "' . $window[7] . '")';
260
        $new = $this->exec($sql);
261
        trace("insertWindow sql=$sql, result=$new");
262
    }
263
264
    public function deleteWindow($window_id)
265
    {
266
        $this->exec('DELETE FROM window WHERE win_id="'.$window_id.'"');
267
    }
268
269
    public function deleteVNCWindow($userid)
270
    {
271
        $winid = $this->querySingle('SELECT win_id FROM window WHERE handler="vnc" AND userid="'.$userid.'"');
272
        require_once('control.php');
273
        wmClose($winid);
274
        $this->deleteWindow($winid);
275
        //$this->exec('DELETE FROM window WHERE handler="vnc" AND userid="'.$userid.'"');
276
    }
277
278
    public function deleteDebug($table, $id, $gt)
279
    {
280
        $this->exec('DELETE FROM '.$table.' WHERE '.$id.' >"'.$gt.'"');
281
    }
282
283
    public function updateWindow($window_id, $field, $value)
284
    {
285
        $this->exec('UPDATE window SET '.$field.'="'.$value.'" WHERE win_id="'.$window_id.'"');
286
    }
287
}
288