1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace Pry\Auth;
14:
15: use Pry\Auth\Bcrypt;
16: use Pry\Auth\Interfaces\OnAutoLoginEvent;
17: use Pry\Session\Session;
18:
19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53:
54: class Auth
55: {
56:
57: const NO_ERROR = 0;
58: const ERROR_LOG = 1;
59: const ERROR_PASS = 2;
60: const ERROR_TABLE = 3;
61: const ERROR_FIELD = 4;
62:
63: 64: 65: 66: 67:
68: private $oDB;
69:
70: 71: 72: 73: 74:
75: private $errorType;
76:
77: 78: 79: 80: 81:
82: private $errorMsg;
83:
84: 85: 86: 87: 88:
89: private $userTable;
90:
91: 92: 93: 94: 95:
96: private $userField;
97:
98: 99: 100: 101: 102:
103: private $pwdField;
104:
105:
106: private $autologTokenField;
107:
108:
109: private $hashRounds;
110:
111: 112: 113: 114: 115:
116: private $autoLogin;
117:
118: 119: 120: 121: 122:
123: private $cookieOption;
124:
125: 126: 127: 128:
129: private $timeOutSession;
130:
131: 132: 133: 134: 135:
136: public $error;
137:
138: 139: 140: 141: 142:
143: private $session;
144:
145: 146: 147: 148: 149: 150: 151:
152: public function __construct(Session $session, \Zend_Db_Adapter_Abstract $db)
153: {
154: $this->oDB = $db;
155: $this->userTable = 'user';
156: $this->userField = 'login';
157: $this->pwdField = 'password';
158: $this->autologTokenField = 'autologKey';
159: $this->autoLogin = false;
160:
161: $this->cookieOption = array(
162: 'name' => 'loginCookie',
163: 'ttl' => time() + (365 * 24 * 3600)
164: );
165: $this->timeOutSession = 0;
166: $this->error = false;
167: $this->errorType = self::NO_ERROR;
168: $this->errorMsg = '';
169: $this->session = $session;
170:
171: if (!isset($session->AC_lastAct))
172: {
173: $session->AC_connected = 0;
174: $session->AC_lastAct = 0;
175: }
176: }
177:
178: 179: 180: 181: 182: 183:
184: public function login($login, $pass)
185: {
186: if ($this->checkUser($login))
187: if ($this->checkPass($login, $pass))
188: {
189: $this->startSession();
190: $this->session->AC_connected = true;
191: $this->session->AC_lastAct = time();
192: if ($this->autoLogin)
193: {
194: $this->createCookie($login);
195: }
196: }
197: else
198: $this->displayError();
199: else
200: $this->displayError();
201: }
202:
203: public function logout()
204: {
205: $this->destroySession();
206: $this->destroyCookie();
207: }
208:
209: 210: 211: 212: 213:
214: public function isLogged()
215: {
216: $lastActivity = time() - $this->session->AC_lastAct;
217:
218: if ($this->session->AC_connected === true && $this->timeOutSession == 0)
219: {
220: $this->session->AC_lastAct = time();
221: if ($lastActivity > 300)
222: $this->session->refresh();
223: return true;
224: }
225:
226: if ($this->session->AC_connected === true && $lastActivity < $this->timeOutSession && $this->timeOutSession != 0)
227: {
228: $this->session->AC_lastAct = time();
229: if ($lastActivity > 300)
230: $this->session->refresh();
231: return true;
232: }
233:
234: if ($this->session->AC_connected === true && $lastActivity > $this->timeOutSession && $this->timeOutSession != 0)
235: {
236: $this->logout();
237: return false;
238: }
239:
240: if (isset($this->session->AC_connected) && !$this->session->AC_connected && $this->autoLogin)
241: {
242: if ($this->loginCookie())
243: return true;
244: else
245: return false;
246: }
247:
248: return false;
249: }
250:
251: 252: 253: 254: 255:
256: public function displayError()
257: {
258: switch ($this->errorType)
259: {
260: case self::ERROR_LOG:
261: $this->errorMsg = 'Identifiant incorrect';
262: break;
263: case self::ERROR_PASS:
264: $this->errorMsg = 'Mot de passe incorrect';
265: break;
266: }
267: return $this->errorMsg;
268: }
269:
270: 271: 272: 273: 274:
275: private function loginCookie()
276: {
277: if (isset($_COOKIE['' . $this->cookieOption['name'] . '']))
278: {
279: $datas = $_COOKIE['' . $this->cookieOption['name'] . ''];
280: $pos = strripos($datas, '|');
281: $login = substr($datas, 0, $pos);
282: $token = substr($datas, $pos + 1);
283:
284: if ($this->checkUser($login))
285: {
286: $prepare = $this->oDB->prepare('SELECT ' . $this->autologTokenField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :logCookie');
287: $prepare->execute(array(':logCookie' => $login));
288: $data = $prepare->fetchColumn();
289:
290: if ($token == $data)
291: {
292: $this->startSession();
293: $this->session->AC_connected = true;
294: $this->session->AC_lastAct = time();
295:
296: $this->destroyCookie();
297: $this->createCookie($login);
298:
299: if (!empty($this->autoLoginEvent))
300: {
301: $this->autoLoginEvent->onAutoLogin($login);
302: }
303:
304: return true;
305: }
306: else
307: {
308: $this->error = true;
309: $this->errorType = self::ERROR_PASS;
310: $this->destroyCookie();
311: $this->displayError();
312: }
313: }
314: else
315: {
316: $this->destroyCookie();
317: $this->displayError();
318: }
319: }
320: return false;
321: }
322:
323: 324: 325: 326:
327: public function startSession($name = 'acauth')
328: {
329: if (empty($this->session))
330: $this->session = Session_Session::getInstance($name, $this->timeOutSession);
331: }
332:
333: 334: 335: 336: 337:
338: private function createCookie($login)
339: {
340: $token = $this->generateRandomToken();
341: $value = $login . '|' . $token;
342: setcookie($this->cookieOption['name'], $value, $this->cookieOption['ttl'], '/');
343:
344:
345: $prep = $this->oDB->prepare('UPDATE ' . $this->userTable . ' SET ' . $this->autologTokenField . ' = :token WHERE ' . $this->userField . ' = :user');
346: $prep->execute(array(
347: ':token' => $token,
348: ':user' => $login
349: ));
350: }
351:
352: private function generateRandomToken()
353: {
354: $token = '';
355: $char = '+-*$=)_!?./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
356: for ($i = 0; $i < 35; $i++)
357: $token .= $char[mt_rand(0, 72)];
358:
359: return sha1($token);
360: }
361:
362: 363: 364: 365:
366: private function destroySession()
367: {
368: $this->session->destroy();
369: }
370:
371: 372: 373: 374:
375: private function destroyCookie()
376: {
377: setcookie($this->cookieOption['name'], NULL, time() - 10, '/');
378: }
379:
380: 381: 382: 383: 384: 385:
386: private function checkUser($user)
387: {
388: $prepare = $this->oDB->prepare('SELECT ' . $this->userField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :user');
389: $prepare->execute(array(':user' => $user));
390: if ($prepare->fetchColumn())
391: return true;
392: else
393: {
394: $this->error = true;
395: $this->errorType = self::ERROR_LOG;
396: return false;
397: }
398: }
399:
400: 401: 402: 403: 404: 405: 406: 407:
408: private function checkPass($login, $pass)
409: {
410: $prepare = $this->oDB->prepare('SELECT ' . $this->pwdField . ' FROM ' . $this->userTable . ' WHERE ' . $this->userField . ' = :login');
411: $prepare->execute(array(':login' => $login));
412: $hash = $prepare->fetchColumn();
413:
414: if (Bcrypt::check($pass, $hash))
415: return true;
416: else
417: {
418: $this->error = true;
419: $this->errorType = self::ERROR_PASS;
420: return false;
421: }
422: }
423:
424: 425: 426: 427: 428: 429: 430:
431: private function hashPass($pass)
432: {
433: 434: 435: 436:
437:
438: $bCrypt = new Bcrypt($this->hashRounds);
439: return $bCrypt->hash($pass);
440: }
441:
442: 443: 444: 445: 446: 447:
448: public function getErrorType()
449: {
450: return $this->errorType;
451: }
452:
453: 454: 455: 456:
457: public function setUserTable($userTable)
458: {
459: $this->userTable = $userTable;
460: }
461:
462: 463: 464: 465:
466: public function setUserField($userField)
467: {
468: $this->userField = $userField;
469: }
470:
471: 472: 473: 474:
475: public function setPwdField($pwdField)
476: {
477: $this->pwdField = $pwdField;
478: }
479:
480: 481: 482: 483:
484: public function setAutologTokenField($autologTokenField)
485: {
486: $this->autologTokenField = $autologTokenField;
487: }
488:
489: 490: 491: 492:
493: public function setHashRounds($hashRounds)
494: {
495: $this->hashRounds = $hashRounds;
496: }
497:
498: 499: 500: 501:
502: public function setAutoLogin($autoLogin)
503: {
504: $this->autoLogin = $autoLogin;
505: }
506:
507: 508: 509: 510: 511:
512: public function setCookieOption($cookieOption)
513: {
514: $this->cookieOption = $cookieOption;
515: }
516:
517: 518: 519: 520:
521: public function setTimeoutSession($timeout)
522: {
523: $this->timeOutSession = $timeout;
524: }
525:
526: 527: 528: 529: 530: 531:
532: public function setOnAutoLoginEvent(OnAutoLoginEvent $event)
533: {
534: $this->autoLoginEvent = $event;
535: }
536:
537: }
538:
539: ?>