]>
Commit | Line | Data |
---|---|---|
d74b3a6d BM |
1 | <?php |
2 | ||
ce25dde2 | 3 | class file_db |
d74b3a6d | 4 | { |
ce25dde2 BM |
5 | public $name = "FileDB"; |
6 | public $author = "Syzop"; | |
d74b3a6d | 7 | public $version = "1.0"; |
ce25dde2 | 8 | public $description = "File-based database backend"; |
d74b3a6d BM |
9 | public $email = "syzop@vulnscan.org"; |
10 | ||
11 | function __construct() | |
12 | { | |
ce25dde2 BM |
13 | Hook::func(HOOKTYPE_USER_LOOKUP, 'file_db::get_user'); |
14 | Hook::func(HOOKTYPE_USERMETA_ADD, 'file_db::add_usermeta'); | |
15 | Hook::func(HOOKTYPE_USERMETA_DEL, 'file_db::del_usermeta'); | |
16 | Hook::func(HOOKTYPE_USERMETA_GET, 'file_db::get_usermeta'); | |
17 | Hook::func(HOOKTYPE_USER_CREATE, 'file_db::user_create'); | |
18 | Hook::func(HOOKTYPE_GET_USER_LIST, 'file_db::get_user_list'); | |
19 | Hook::func(HOOKTYPE_USER_DELETE, 'file_db::user_delete'); | |
20 | Hook::func(HOOKTYPE_EDIT_USER, 'file_db::edit_core'); | |
21 | Hook::func(HOOKTYPE_PRE_OVERVIEW_CARD, 'file_db::add_pre_overview_card'); | |
d74b3a6d BM |
22 | AuthModLoaded::$status = 1; |
23 | ||
ce25dde2 | 24 | file_db::read_db(); |
d74b3a6d BM |
25 | |
26 | if (defined('DEFAULT_USER')) // we've got a default account | |
27 | { | |
28 | $lkup = new PanelUser(DEFAULT_USER['username']); | |
29 | ||
30 | if (!$lkup->id) // doesn't exist, add it with full privileges | |
31 | { | |
32 | $user = []; | |
33 | $user['user_name'] = DEFAULT_USER['username']; | |
34 | $user['user_pass'] = DEFAULT_USER['password']; | |
35 | $user['err'] = ""; | |
36 | create_new_user($user); | |
37 | } | |
38 | $lkup = new PanelUser(DEFAULT_USER['username']); | |
39 | if (!user_can($lkup, PERMISSION_MANAGE_USERS)) | |
40 | $lkup->add_permission(PERMISSION_MANAGE_USERS); | |
41 | } | |
42 | } | |
43 | ||
d74b3a6d BM |
44 | public static function add_pre_overview_card($empty) |
45 | { | |
46 | if (defined('DEFAULT_USER')) | |
47 | Message::Fail("Warning: DEFAULT_USER is set in config.php. You should remove that item now, as it is only used during installation."); | |
48 | } | |
49 | ||
d74b3a6d BM |
50 | public static function get_user_helper($item) |
51 | { | |
52 | $obj = (object) []; | |
53 | $obj->id = $item["id"]; | |
54 | $obj->username = $item["username"]; | |
55 | $obj->passhash = $item["password"]; | |
56 | $obj->first_name = $item["first_name"]; | |
57 | $obj->last_name = $item["last_name"]; | |
58 | $obj->created = $item["created"]; | |
59 | $obj->bio = $item["bio"]; | |
60 | $obj->email = $item["email"]; | |
61 | $obj->user_meta = (new PanelUser_Meta($obj->id))->list; | |
62 | return $obj; | |
63 | } | |
64 | ||
65 | public static function uid_to_username($id) | |
66 | { | |
67 | GLOBAL $db; | |
68 | foreach($db["users"] as $user=>$details) | |
69 | if ($details["id"] === $id) | |
70 | return $details["username"]; | |
71 | return null; | |
72 | } | |
73 | ||
74 | /* We convert $u with a full user as an object ;D*/ | |
75 | public static function get_user(&$u) | |
76 | { | |
77 | GLOBAL $db; | |
78 | ||
79 | $id = $u['id']; | |
80 | $name = $u['name']; | |
81 | ||
82 | $obj = (object) []; | |
83 | if ($id) | |
84 | { | |
85 | foreach($db["users"] as $user=>$details) | |
86 | if ($details["id"] === $id) | |
ce25dde2 | 87 | $obj = file_db::get_user_helper($details); |
d74b3a6d BM |
88 | } |
89 | if (isset($db["users"][$name])) | |
90 | { | |
ce25dde2 | 91 | $obj = file_db::get_user_helper($db["users"][$name]); |
d74b3a6d BM |
92 | } |
93 | $u['object'] = $obj; | |
94 | return $obj; | |
95 | } | |
96 | ||
97 | public static function get_usermeta(&$u) | |
98 | { | |
99 | GLOBAL $db; | |
100 | ||
101 | $uid = $u['id']; | |
102 | ||
ce25dde2 | 103 | $username = file_db::uid_to_username($uid); |
d74b3a6d BM |
104 | if (!$username) |
105 | die("User not found: $uid\n"); // return false; /* User does not exist */ | |
106 | ||
107 | $u['meta'] = $db["users"][$username]['meta']; | |
108 | } | |
109 | ||
110 | public static function add_usermeta(&$meta) | |
111 | { | |
112 | GLOBAL $db; | |
113 | ||
114 | $meta = $meta['meta']; | |
115 | $uid = $meta['id']; | |
116 | $key = $meta['key']; | |
117 | $value = $meta['value']; | |
118 | ||
ce25dde2 BM |
119 | file_db::read_db(); |
120 | $username = file_db::uid_to_username($uid); | |
d74b3a6d BM |
121 | if (!$username) |
122 | return false; /* User does not exist */ | |
123 | ||
124 | /* And update */ | |
125 | $db["users"][$username]["meta"][$key] = $value; | |
ce25dde2 | 126 | file_db::write_db(); |
d74b3a6d BM |
127 | return true; |
128 | } | |
129 | ||
c53841fe | 130 | public static function del_usermeta(&$meta) |
d74b3a6d | 131 | { |
c53841fe BM |
132 | GLOBAL $db; |
133 | ||
134 | $meta = $meta['meta']; | |
d74b3a6d BM |
135 | $uid = $meta['id']; |
136 | $key = $meta['key']; | |
137 | ||
ce25dde2 BM |
138 | file_db::read_db(); |
139 | $username = file_db::uid_to_username($uid); | |
d74b3a6d BM |
140 | if (!$username) |
141 | return false; /* User does not exist */ | |
142 | ||
143 | /* And delete */ | |
144 | unset($db["users"][$username]["meta"][$key]); | |
145 | ||
ce25dde2 | 146 | file_db::write_db(); |
d74b3a6d BM |
147 | return true; |
148 | } | |
149 | ||
57eb6560 | 150 | public static function minimal_db() |
d74b3a6d BM |
151 | { |
152 | GLOBAL $db; | |
d74b3a6d BM |
153 | /* Add at least the general arrays: */ |
154 | if (!isset($db["users"])) | |
155 | $db["users"] = []; | |
22db6e99 BM |
156 | if (!isset($db["settings"])) |
157 | $db["settings"] = []; | |
d74b3a6d BM |
158 | /* Initialize more if we ever add more... */ |
159 | } | |
57eb6560 BM |
160 | public static function read_db() |
161 | { | |
162 | GLOBAL $db; | |
163 | $db_filename = UPATH.'/data/database.php'; | |
164 | @include($db_filename); | |
ce25dde2 | 165 | file_db::minimal_db(); |
57eb6560 BM |
166 | } |
167 | ||
168 | /* Delete the database -- only called during setup AFTER confirmation! */ | |
169 | public static function delete_db() | |
170 | { | |
171 | GLOBAL $db; | |
172 | $db = []; | |
ce25dde2 BM |
173 | file_db::minimal_db(); |
174 | file_db::write_db(true); | |
57eb6560 | 175 | } |
d74b3a6d BM |
176 | |
177 | public static function write_db($force = false) | |
178 | { | |
179 | GLOBAL $db; | |
180 | /* Refuse to write empty db (or nearly empty) */ | |
311c294b | 181 | if (empty($db) || (empty($db["users"]) && empty($db["settings"])) && !$force) |
d74b3a6d BM |
182 | return; |
183 | ||
184 | $db_filename = UPATH.'/data/database.php'; | |
185 | $tmpfile = UPATH.'/data/database.tmp.'.bin2hex(random_bytes(8)).'.php'; // hmm todo optional location? :D | |
186 | $fd = fopen($tmpfile, "w"); | |
187 | if (!$fd) | |
188 | die("Could not write to temporary database file $tmpfile.<br>We need write permissions on the data/ directory!<br>"); | |
189 | ||
190 | $str = var_export($db, true); | |
191 | if ($str === null) | |
192 | die("Error while running write_db() -- weird!"); | |
193 | if (!fwrite($fd, "<?php\n". | |
194 | "/* This database file is written automatically by the UnrealIRCd webpanel.\n". | |
195 | " * You are not really supposed to edit it manually.\n". | |
196 | " */\n". | |
b41fa16f | 197 | '$db = '.$str.";\n")) |
d74b3a6d BM |
198 | { |
199 | die("Error writing to database file $tmpfile (on fwrite).<br>"); | |
200 | } | |
201 | if (!fclose($fd)) | |
202 | die("Error writing to database file $tmpfile (on close).<br>"); | |
203 | /* Now atomically rename the file */ | |
204 | if (!rename($tmpfile, $db_filename)) | |
205 | die("Could not write (rename) to file ".$db_filename."<br>"); | |
9f303b7c BM |
206 | if (function_exists('opcache_invalidate')) |
207 | opcache_invalidate($db_filename); | |
d74b3a6d BM |
208 | } |
209 | ||
210 | public static function user_create(&$u) | |
211 | { | |
212 | GLOBAL $db; | |
213 | ||
214 | $username = $u['user_name']; | |
215 | $first_name = $u['fname'] ?? NULL; | |
216 | $last_name = $u['lname'] ?? NULL; | |
217 | $password = $u['user_pass'] ?? NULL; | |
218 | $user_bio = $u['user_bio'] ?? NULL; | |
219 | $user_email = $u['user_email'] ?? NULL; | |
220 | $created = date("Y-m-d H:i:s"); | |
221 | $id = random_int(1000000,99999999); | |
222 | ||
ce25dde2 | 223 | file_db::read_db(); |
d74b3a6d BM |
224 | |
225 | if (isset($db["users"][$username])) | |
226 | { | |
227 | $u['errmsg'][] = "Could not add user: user already exists"; | |
228 | return; | |
229 | } | |
230 | ||
231 | $db["users"][$username] = [ | |
232 | "id" => $id, | |
233 | "username" => $username, | |
234 | "first_name" => $first_name, | |
235 | "last_name" => $last_name, | |
236 | "password" => $password, | |
237 | "bio" => $user_bio, | |
238 | "email" => $user_email, | |
239 | "created" => $created, | |
240 | "meta" => [], | |
241 | ]; | |
242 | ||
ce25dde2 | 243 | file_db::write_db(); |
d74b3a6d BM |
244 | $u['success'] = true; |
245 | } | |
246 | ||
247 | public static function get_user_list(&$list) | |
248 | { | |
249 | GLOBAL $db; | |
250 | ||
251 | $userlist = []; | |
252 | foreach($db["users"] as $user=>$details) | |
253 | { | |
254 | $userlist[] = new PanelUser(NULL, $details['id']); | |
255 | } | |
256 | if (!empty($userlist)) | |
257 | $list = $userlist; | |
258 | ||
259 | } | |
260 | ||
261 | public static function user_delete(&$u) | |
262 | { | |
263 | GLOBAL $db; | |
264 | ||
ce25dde2 | 265 | file_db::read_db(); |
d74b3a6d BM |
266 | $user = $u['user']; |
267 | $username = $user->username; | |
268 | $deleted = false; | |
269 | if (isset($db["users"][$username])) | |
270 | { | |
271 | unset($db["users"][$username]); | |
272 | $deleted = true; | |
273 | } | |
ce25dde2 | 274 | file_db::write_db(true); |
d74b3a6d BM |
275 | |
276 | if ($deleted) | |
277 | { | |
278 | $u['info'][] = "Successfully deleted user \"$user->username\""; | |
279 | $u['boolint'] = 1; | |
280 | } else { | |
281 | $u['info'][] = "Unknown error"; | |
282 | $u['boolint'] = 0; | |
283 | } | |
284 | } | |
285 | ||
286 | public static function edit_core($arr) | |
287 | { | |
288 | GLOBAL $db; | |
289 | ||
290 | $user = $arr['user']; | |
291 | $username = $user->username; | |
292 | $info = $arr['info']; | |
293 | ||
ce25dde2 | 294 | file_db::read_db(); |
d74b3a6d BM |
295 | |
296 | foreach($info as $key => $val) | |
297 | { | |
298 | $keyname = NULL; | |
299 | if (!$val || !strlen($val) || BadPtr($val)) | |
300 | continue; | |
301 | if (!strcmp($key,"update_fname") && $val != $user->first_name) | |
302 | { | |
303 | $keyname = "first_name"; | |
304 | $property_name = "first name"; | |
305 | } | |
306 | elseif (!strcmp($key,"update_lname") && $val != $user->last_name) | |
307 | { | |
308 | $keyname = "last_name"; | |
309 | $property_name = "last name"; | |
310 | } | |
311 | elseif (!strcmp($key,"update_bio") && $val != $user->bio) | |
312 | { | |
313 | $keyname = "bio"; | |
314 | $property_name = "bio"; | |
315 | } | |
316 | elseif (!strcmp($key,"update_pass") || !strcmp($key,"update_pass_conf")) | |
317 | { | |
318 | $keyname = "password"; | |
319 | $property_name = "password"; | |
320 | } | |
321 | elseif(!strcmp($key,"update_email") && $val != $user->email) | |
322 | { | |
323 | $keyname = "email"; | |
324 | $property_name = "email address"; | |
325 | } | |
326 | ||
327 | if (!$keyname) | |
328 | continue; | |
329 | ||
330 | if (isset($db["users"][$username])) | |
331 | { | |
332 | $db["users"][$username][$keyname] = $val; | |
333 | Message::Success("Successfully updated the $property_name for $user->username"); | |
334 | } else { | |
335 | Message::Fail("Could not update $property_name for $user->username: ".$stmt->errorInfo()[0]." (CODE: ".$stmt->errorCode().")"); | |
336 | } | |
337 | } | |
338 | ||
ce25dde2 | 339 | file_db::write_db(true); |
d74b3a6d BM |
340 | } |
341 | } | |
311c294b BM |
342 | |
343 | class DbSettings { | |
344 | public static function get() | |
345 | { | |
346 | GLOBAL $db; | |
347 | ||
348 | if (!isset($db) || empty($db)) | |
ce25dde2 | 349 | file_db::read_db(); |
311c294b BM |
350 | |
351 | return $db["settings"]; | |
352 | } | |
353 | public static function set($key, $val) : bool | |
354 | { | |
355 | GLOBAL $db; | |
356 | ||
ce25dde2 | 357 | file_db::read_db(); |
311c294b | 358 | $db["settings"][$key] = $val; |
ce25dde2 | 359 | file_db::write_db(); |
311c294b BM |
360 | return true; |
361 | } | |
362 | } |