1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
27: class WsAuth
28: {
29: 30: 31: 32:
33: public $isUsable;
34: private $_db;
35:
36:
37: public function __construct()
38: {
39:
40: $this->_db = new WsDatabase();
41:
42: if (!$this->_db->isConnected) {
43: $this->isUsable = false;
44: return false;
45: } else {
46: $this->isUsable = true;
47: }
48:
49:
50: if (WsConfig::get('db_driver') === 'pgsql') {
51: $create_table = '
52: CREATE TABLE IF NOT EXISTS ws_user (
53: id SERIAL PRIMARY KEY,
54: email VARCHAR(128) NOT NULL,
55: password VARCHAR(128) NOT NULL,
56: user_salt VARCHAR(50) NOT NULL,
57: is_verified BOOLEAN NOT NULL,
58: is_active BOOLEAN NOT NULL,
59: verification_code VARCHAR(65) NOT NULL
60: );
61: ';
62: $this->_db->execute($create_table);
63: $create_table = '
64: CREATE TABLE IF NOT EXISTS ws_logged_in (
65: id SERIAL PRIMARY KEY,
66: user_id INTEGER NOT NULL REFERENCES ws_user(id),
67: session_id CHAR(32) NOT NULL,
68: token CHAR(128) NOT NULL
69: );
70: ';
71: $this->_db->execute($create_table);
72: $create_table = '
73: CREATE TABLE IF NOT EXISTS ws_roles (
74: id SERIAL PRIMARY KEY,
75: name VARCHAR(25) NOT NULL,
76: description VARCHAR(50)
77: );
78: ';
79: $this->_db->execute($create_table);
80: $create_table = '
81: CREATE TABLE IF NOT EXISTS ws_permissions (
82: id SERIAL PRIMARY KEY,
83: name VARCHAR(25) NOT NULL,
84: description VARCHAR(50)
85: );
86: ';
87: $this->_db->execute($create_table);
88: $create_table = '
89: CREATE TABLE IF NOT EXISTS ws_role_perm (
90: role_id INTEGER NOT NULL REFERENCES ws_roles(id),
91: permissions_id INTEGER NOT NULL REFERENCES ws_permissions(id)
92: );
93: ';
94: $this->_db->execute($create_table);
95: $create_table = '
96: CREATE TABLE IF NOT EXISTS ws_user_role (
97: user_id INTEGER NOT NULL REFERENCES ws_user(id),
98: role_id INTEGER NOT NULL REFERENCES ws_roles(id)
99: );
100: ';
101: $this->_db->execute($create_table);
102:
103:
104: } else if (WsConfig::get('db_driver') === 'mysql') {
105: $create_table = '
106: CREATE TABLE IF NOT EXISTS ws_user (
107: id INTEGER PRIMARY KEY AUTO_INCREMENT,
108: email VARCHAR(128) NOT NULL,
109: password VARCHAR(128) NOT NULL,
110: user_salt VARCHAR(50) NOT NULL,
111: is_verified BOOLEAN NOT NULL,
112: is_active BOOLEAN NOT NULL,
113: verification_code VARCHAR(65) NOT NULL
114: );
115: ';
116: $this->_db->execute($create_table);
117: $create_table = '
118: CREATE TABLE IF NOT EXISTS ws_logged_in (
119: id INTEGER PRIMARY KEY AUTO_INCREMENT,
120: user_id INTEGER NOT NULL,
121: session_id CHAR(32) NOT NULL,
122: token CHAR(128) NOT NULL,
123:
124: FOREIGN KEY (user_id) REFERENCES ws_user(id)
125: );
126: ';
127: $this->_db->execute($create_table);
128: $create_table = '
129: CREATE TABLE IF NOT EXISTS ws_roles (
130: id INTEGER PRIMARY KEY AUTO_INCREMENT,
131: name VARCHAR(25) NOT NULL,
132: description VARCHAR(50)
133: );
134: ';
135: $this->_db->execute($create_table);
136: $create_table = '
137: CREATE TABLE IF NOT EXISTS ws_permissions (
138: id INTEGER PRIMARY KEY AUTO_INCREMENT,
139: name VARCHAR(25) NOT NULL,
140: description VARCHAR(50)
141: );
142: ';
143: $this->_db->execute($create_table);
144: $create_table = '
145: CREATE TABLE IF NOT EXISTS ws_role_perm (
146: role_id INTEGER NOT NULL,
147: permissions_id INTEGER NOT NULL,
148:
149: FOREIGN KEY (role_id) REFERENCES ws_roles(id),
150: FOREIGN KEY (permissions_id) REFERENCES ws_permissions(id)
151: );
152: ';
153: $this->_db->execute($create_table);
154: $create_table = '
155: CREATE TABLE IF NOT EXISTS ws_user_role (
156: user_id INTEGER NOT NULL,
157: role_id INTEGER NOT NULL,
158:
159: FOREIGN KEY (user_id) REFERENCES ws_user(id),
160: FOREIGN KEY (role_id) REFERENCES ws_roles(id)
161: );
162: ';
163: $this->_db->execute($create_table);
164:
165:
166: } else if (WsConfig::get('db_driver') === 'sqlite') {
167: $create_table = '
168: CREATE TABLE IF NOT EXISTS ws_user (
169: id INTEGER PRIMARY KEY AUTOINCREMENT,
170: email VARCHAR(128) NOT NULL,
171: password VARCHAR(128) NOT NULL,
172: user_salt VARCHAR(50) NOT NULL,
173: is_verified BOOLEAN NOT NULL,
174: is_active BOOLEAN NOT NULL,
175: verification_code VARCHAR(65) NOT NULL
176: );
177: ';
178: $this->_db->execute($create_table);
179: $create_table = '
180: CREATE TABLE IF NOT EXISTS ws_logged_in (
181: id INTEGER PRIMARY KEY AUTOINCREMENT,
182: user_id INTEGER NOT NULL,
183: session_id CHAR(32) NOT NULL,
184: token CHAR(128) NOT NULL,
185:
186: FOREIGN KEY (user_id) REFERENCES ws_user(id)
187: );
188: ';
189: $this->_db->execute($create_table);
190: $create_table = '
191: CREATE TABLE IF NOT EXISTS ws_roles (
192: id INTEGER PRIMARY KEY AUTOINCREMENT,
193: name VARCHAR(25) NOT NULL,
194: description VARCHAR(50)
195: );
196: ';
197: $this->_db->execute($create_table);
198: $create_table = '
199: CREATE TABLE IF NOT EXISTS ws_permissions (
200: id INTEGER PRIMARY KEY AUTOINCREMENT,
201: name VARCHAR(25) NOT NULL,
202: description VARCHAR(50)
203: );
204: ';
205: $this->_db->execute($create_table);
206: $create_table = '
207: CREATE TABLE IF NOT EXISTS ws_role_perm (
208: role_id INTEGER NOT NULL,
209: permissions_id INTEGER NOT NULL,
210:
211: FOREIGN KEY (role_id) REFERENCES ws_roles(id),
212: FOREIGN KEY (permissions_id) REFERENCES ws_permissions(id)
213: );
214: ';
215: $this->_db->execute($create_table);
216: $create_table = '
217: CREATE TABLE IF NOT EXISTS ws_user_role (
218: user_id INTEGER NOT NULL,
219: role_id INTEGER NOT NULL,
220:
221: FOREIGN KEY (user_id) REFERENCES ws_user(id),
222: FOREIGN KEY (role_id) REFERENCES ws_roles(id)
223: );
224: ';
225: $this->_db->execute($create_table);
226: }
227:
228:
229: $this->createAdminUser();
230:
231: unset($create_table);
232: }
233:
234:
235: 236: 237: 238: 239:
240: private function createAdminUser()
241: {
242: if (!$this->isUsable) {
243: return false;
244: }
245:
246:
247: $email = WsConfig::get('auth_admin');
248:
249:
250: $user_model = new Ws_userModel();
251:
252:
253: $user_model->search("email='$email'");
254: if ($user_model->nRows > 0) {
255: return WS_AUTH_USER_EXISTS;
256: }
257:
258:
259: $user_model->email = $email;
260: $user_model->is_verified = true;
261: $user_model->is_active = true;
262: $user_model->password = 'admin';
263: $user_model->verification_code = $user_model->randomString(65);
264:
265: $user_model->save();
266:
267: return true;
268: }
269:
270:
271: 272: 273: 274: 275: 276: 277: 278:
279: public function createUser($email, $password)
280: {
281: if (!$this->isUsable) {
282: return false;
283: }
284:
285:
286: $user_model = new Ws_userModel();
287:
288:
289: $user_model->search("email='$email'");
290: if ($user_model->nRows > 0) {
291: return WS_AUTH_USER_EXISTS;
292: }
293:
294:
295: $user_model->email = $email;
296: if (WsConfig::get('db_driver') == 'pgsql') {
297: $user_model->is_verified = 'f';
298: $user_model->is_active = 'f';
299: } else {
300: $user_model->is_verified = 0;
301: $user_model->is_active = 0;
302: }
303: $user_model->password = $password;
304: $verification_code = $user_model->randomString(65);
305: $user_model->verification_code = $verification_code;
306:
307: if ($user_model->save()) {
308: if (
309: filter_input(INPUT_SERVER, 'SERVER_NAME', FILTER_SANITIZE_STRING)
310: == 'localhost') {
311: $server = filter_input(INPUT_SERVER, 'SERVER_ADDR',
312: FILTER_SANITIZE_STRING);
313: } else {
314: $server = filter_input(INPUT_SERVER, 'SERVER_NAME',
315: FILTER_SANITIZE_URL);
316: }
317: $link = 'http://'.$server
318: .WsUrl::link('Wsauth', 'verify', array(
319: 'code'=>$verification_code
320: ));
321:
322:
323: $to = $email;
324:
325: $subject = WsConfig::get('app_name')
326: .WsLocalize::msg(' - Thank you for registering');
327:
328: $html = "
329: <HTML>
330: <HEAD>
331: <TITLE>$subject</TITLE>
332: </HEAD>
333: <BODY>
334: Welcome,
335: <BR/>
336: <BR/>
337: ";
338: $html .= '<p>';
339: $html .= WsLocalize::msg('We sent you this email to verify your email address.');
340: $html .= WsLocalize::msg('To complete user registration, click on the following link');
341: $html .= '</p>';
342: $html .= '<p><a href="'.$link.'">';
343: $html .= WsLocalize::msg('finish registration');
344: $html .= '</a></p>'.$link;
345: $html .= '<br/>';
346: $html .= WsLocalize::msg('Thank you and welcome.');
347: $html .= '</BODY></HTML>';
348:
349: $headers = "MIME-Version: 1.0\r\n";
350: $headers .= "Content-type: text/html; charset=utf-8\r\n";
351: $headers .= 'From: <'
352: .WsConfig::get('auth_admin').'>'."\r\n";
353:
354:
355: mail($to, $subject, $html, $headers);
356: return true;
357: } else {
358: return false;
359: }
360: }
361:
362:
363: 364: 365: 366: 367: 368: 369: 370:
371: public function login($email, $password)
372: {
373:
374: if (!$this->isUsable) {
375: return false;
376: }
377:
378: $user_model = new Ws_userModel();
379: $user_model->search("email='$email'");
380:
381: if ($user_model->nRows != 1) {
382: return WS_AUTH_NO_MATCH;
383: }
384:
385:
386: $password1 = $user_model->user_salt.$password;
387: $password2 = $user_model->hashData($password1);
388:
389:
390: $user_model->search("email='$email' AND password='$password2'");
391:
392: if ($user_model->nRows != 1) {
393: return WS_AUTH_NO_MATCH;
394: }
395:
396:
397: $is_active = (boolean)$user_model->is_active;
398: $is_verified = (boolean)$user_model->is_verified;
399:
400:
401: if (!$is_verified) {
402:
403: return WS_AUTH_NOT_VERIFIED;
404: }
405:
406:
407: if (!$is_active) {
408: return WS_AUTH_NOT_ACTIVE;
409: }
410:
411:
412: $random = $user_model->randomString();
413:
414: $token = filter_input(INPUT_SERVER, 'HTTP_USER_AGENT',
415: FILTER_SANITIZE_STRING).$random;
416: $token = $user_model->hashData($token);
417:
418: $user_id = $user_model->id;
419:
420: $session_id = session_id();
421:
422:
423: $_SESSION['ws_auth_token'] = $token;
424: $_SESSION['ws_auth_user_id'] = $user_id;
425: $_SESSION['ws_auth_user_email'] = $user_model->email;
426: $_SESSION['ws_auth_generated_time'] = time();
427: $_SESSION['ws_auth_client_ip'] =
428: filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_STRING);
429: $_SESSION['ws_auth_user_agent'] =
430: filter_input(INPUT_SERVER,'HTTP_USER_AGENT',FILTER_SANITIZE_STRING);
431:
432: $logged_in_model = new Ws_logged_inModel();
433:
434: $logged_in_model->search("user_id=$user_id");
435: $logged_in_model->delete();
436:
437:
438: $logged_in_model->user_id = $user_id;
439: $logged_in_model->session_id = $session_id;
440: $logged_in_model->token = $token;
441: $logged_in_model->save();
442:
443: return WS_AUTH_LOGIN_OK;
444: }
445:
446:
447: 448: 449: 450: 451: 452:
453: public function checkSession()
454: {
455: if (!isset($_SESSION['ws_auth_user_id'])) {
456: return false;
457: }
458:
459:
460: if(!isset($_SESSION['ws_auth_generated_time'])) {
461: return false;
462: }
463: if (time() > ($_SESSION['ws_auth_generated_time'] + 3600)) {
464: return false;
465: }
466:
467:
468: if(!isset($_SESSION['ws_auth_client_ip'])) {
469: return false;
470: }
471: if ($_SESSION['ws_auth_client_ip'] !==
472: filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_SANITIZE_STRING)) {
473: return false;
474: }
475:
476:
477: if(!isset($_SESSION['ws_auth_user_agent'])) {
478: return false;
479: }
480: if ($_SESSION['ws_auth_user_agent'] !==
481: filter_input(INPUT_SERVER, 'HTTP_USER_AGENT',
482: FILTER_SANITIZE_STRING)) {
483: return false;
484: }
485:
486:
487: $user_id = $_SESSION['ws_auth_user_id'];
488: $logged_in_model = new Ws_logged_inModel();
489: $logged_in_model->search("user_id=$user_id");
490:
491:
492: if ($logged_in_model->nRows >= 1) {
493:
494: if(session_id() == trim($logged_in_model->session_id)
495: && $_SESSION['ws_auth_token'] == trim($logged_in_model->token)){
496:
497:
498: $_SESSION['ws_auth_generated_time'] = time();
499:
500: 501: 502:
503: return true;
504: }
505: }
506:
507: return false;
508: }
509:
510:
511: 512: 513: 514: 515: 516:
517: public function logout()
518: {
519: if (!$this->checkSession()) {
520: return false;
521: }
522:
523: $user_id = $_SESSION['ws_auth_user_id'];
524: $logged_in_model = new Ws_logged_inModel();
525:
526: $logged_in_model->search("user_id=$user_id");
527: $logged_in_model->delete();
528:
529:
530: $_SESSION = array();
531:
532: session_destroy();
533:
534: return true;
535: }
536:
537:
538: 539: 540: 541: 542: 543: 544:
545: public function hasPermission($perm)
546: {
547:
548: if (!$this->checkSession()) {
549: return false;
550: }
551:
552:
553: if ($_SESSION['ws_auth_user_email'] === WsConfig::get('auth_admin')) {
554: return true;
555: } else if ($perm === 'admin' and (
556: $_SESSION['ws_auth_user_email'] === WsConfig::get('auth_admin')
557: )) {
558: return true;
559: }
560:
561: $db = new WsDatabase();
562: $user_id = $_SESSION['ws_auth_user_id'];
563:
564:
565: $sql = '
566: SELECT
567: wp.id
568: FROM ws_permissions wp,
569: ws_role_perm rp,
570: ws_roles wr,
571: ws_user_role wur,
572: ws_user wu
573: WHERE wp.id=rp.permissions_id
574: AND rp.role_id=wr.id
575: AND wr.id=wur.role_id
576: AND wur.user_id=wu.id
577: AND wu.id=:user_id
578: AND wp.name=:perm
579: GROUP BY wp.id
580: ';
581: $db->query($sql, array(
582: 'user_id' => $user_id,
583: 'perm' => $perm
584: ));
585:
586: if ($db->nRows >= 1) {
587: return true;
588: }
589:
590: return false;
591: }
592:
593:
594: 595: 596: 597: 598: 599:
600: public function currentUser()
601: {
602:
603: if (!$this->checkSession()) {
604: return '';
605: }
606:
607: return($_SESSION['ws_auth_user_email']);
608: }
609:
610:
611: 612: 613: 614: 615: 616:
617: public function currentUserID()
618: {
619:
620: if (!$this->checkSession()) {
621: return -1;
622: }
623:
624: return($_SESSION['ws_auth_user_id']);
625: }
626: }
627:
628: