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