· 6 years ago · Dec 04, 2019, 11:08 AM
1<?php
2Class Models_Session extends Base_Model {
3
4 private $tablename = 'space_sso_session';
5
6 public function __construct() {
7 parent::__construct('mysql');
8 }
9
10 /**
11 * login counter
12 * @param string $encryptedMsisdn
13 */
14 public function getLoginCounter($encryptedMsisdn){
15 if($this->cache !== false){
16 // cache enable
17 $counter = $this->cache->get('LOGIN_ATTEMPT_' . $encryptedMsisdn);
18 $this->logger->write('debug', 'LOGIN ATTEMPT FOR ' . $encryptedMsisdn .' is ' . ((int)$counter));
19 if($counter !== false) {
20 $this->cache->delete('LOGIN_ATTEMPT_' . $encryptedMsisdn);
21 $this->cache->set('LOGIN_ATTEMPT_' . $encryptedMsisdn, (int)$counter + 1);
22 return (int)$counter + 1;
23 }
24 else{
25 $this->cache->set('LOGIN_ATTEMPT_' . $encryptedMsisdn, 1);
26 return 1;
27 }
28 }
29 else{
30 // cache disable
31 //@todo:
32 }
33 }
34
35 /**
36 * reset signin counter
37 * @param string $encryptedMsisdn
38 */
39 public function resetSigninCounter($encryptedMsisdn){
40 if($this->cache !== false){
41 // cache enabled
42 $this->cache->delete('LOGIN_ATTEMPT_' . $encryptedMsisdn);
43 }
44 else{
45 // cache disabled
46 //@todo
47 }
48 }
49
50 /**
51 * Pairing Token to unique msisdn
52 * @param string $token
53 * @param string $msisdn
54 * @param string $field
55 * author ariska 2016 04 18
56 */
57 public function MappingUniqueToken($token,$msisdn,$field){
58 // sanitize input
59 $token = $this->_escape($token);
60
61 $sql = sprintf("SELECT count(msisdn) as total , %s as identity FROM %s WHERE expired>=now() AND token='%s' AND msisdn='%s'",
62 $field,
63 $tablename,
64 $token,
65 $msisdn
66 );
67 $this->logger->write('debug', 'QUERY MAPPING_UNIQUE_TOKEN: ' . $sql);
68 $result = $this->db->fetchOne($sql);
69 $this->logger->write('debug', 'RESULT MAPPING_UNIQUE_TOKEN: ' . print_r($result,1));
70 /*
71 total = 0 =>
72 1. tempered token
73 2. token without signin
74 3. token unpaired msisdn
75 */
76 if($result['total'] === '0'){
77 return false;
78 } else {
79 return true;
80 }
81 }
82
83 /**
84 * check token if valid/invalid or expired
85 *
86 * @param string $token
87 * @return mixed true/false/expired
88 */
89 public function isValidToken($token) {
90 // check from cache
91 if($this->cache !== false){
92 $status = $this->cache->get('TOKEN_'.$token);
93 if($status !== false) {
94 if($status === 'false') $status = false;
95 $this->logger->write('debug', 'CACHED ISVALIDTOKEN: '.$status);
96 return $status;
97 }
98 }
99
100 // sanitize input
101 $token = $this->_escape($token);
102
103 if($this->_userTypeFromToken($token) == 'SUBSCRIBER'){
104 //$tablename = $this->_getTablename($token);
105 $a = explode('-', $token);
106 $index = $a[count($a)-1];
107 $tablename = $this->tablename . '_' . $index;
108 $field = 'msisdn';
109 }
110 else{
111 $tablename = $this->tablename;
112 $field = 'user_name';
113 }
114
115 // check ip
116 //$tmp = explode('_',$token);
117 //if(isset($_SERVER['SERVER_ADDR'])){
118 // if( strpos($_SERVER['SERVER_ADDR'], ',') !== false ){
119 // $sandbox = explode(',', $_SERVER['SERVER_ADDR']);
120 // $ip = ip2long($sandbox[count($sandbox)-1]);
121 // }
122 // else{
123 // $ip = ip2long($_SERVER['SERVER_ADDR']);
124 // }
125 // if($ip != $tmp[0]){
126 // return false;
127 // }
128 //}
129
130 $sql = sprintf("SELECT count(token) as total, IF(expired<=now(),1,0) as expired,%s as identity FROM %s WHERE token='%s'",
131 $field,
132 $tablename,
133 $token
134 );
135
136 $this->logger->write('debug', 'QUERY IS_VALID_TOKEN: ' . $sql);
137 $result = $this->db->fetchOne($sql);
138 $this->logger->write('debug', 'RESULT IS_VALID_TOKEN: ' . print_r($result,1));
139
140 if($result['total'] == 0){
141 if($this->cache !== false) {
142 $this->cache->set('TOKEN_'.$token, 'false');
143 $this->logger->write('debug', 'CACHED KEY: TOKEN_'.$token.' VALUE: false');
144 }
145 return false;
146 }
147 else{
148 if($result['expired'] == '1'){
149 if($this->cache !== false) {
150 $this->cache->set('TOKEN_'.$token, 'expired');
151 $this->logger->write('debug', 'CACHED KEY: TOKEN_'.$token.' VALUE: expired');
152 }
153 return 'expired';
154 }
155 else{
156
157/* if($this->cache !== false) {
158 $this->cache->set('TOKEN_'.$token, 'true');
159 $this->logger->write('debug', 'CACHED KEY: TOKEN_'.$token.' VALUE: true');
160 }
161 return $result['identity'];
162//*/
163 if($this->MappingUniqueToken($token,$msisdn,$field) !== false) {
164 if($this->cache !== false) {
165 $this->cache->set('TOKEN_'.$token, 'true');
166 $this->logger->write('debug', 'CACHED KEY: TOKEN_'.$token.' VALUE: true');
167 }
168 return $result['identity'];
169 } else {
170 $this->logger->write('debug', 'TEMPERED TOKEN: TOKEN_'.$token.' MSISDN: '.$msisdn);
171 return false;
172 }
173 }
174 }
175 }
176
177 /**
178 * purge session
179 *
180 * @param string $token
181 */
182 public function purge($userType, $token) {
183
184 $token = $this->_escape($token);
185
186 if($userType == 'SUBSCRIBER'){
187 //$tablename = $this->_getTablename($token);
188 $a = explode('-', $token);
189 $index = $a[count($a)-1];
190 $tablename = $this->tablename . '_' . $index;
191
192 //-- new
193 //
194 // logging duration
195 //
196
197 $sql = "CREATE TABLE IF NOT EXISTS space.space_sso_duration_log_" .date('Ymd'). " LIKE space.space_sso_duration_log";
198 $this->db->query($sql);
199 $sql = "INSERT INTO
200 space.space_sso_duration_log_" .date('Ymd'). "
201 (date_time, msisdn, channel_group, duration)
202 SELECT
203 now(),
204 msisdn,
205 channel,
206 TIME_TO_SEC(TIMEDIFF(now(),created)) as duration
207 FROM
208 $tablename
209 WHERE
210 token='$token'
211 ";
212 $this->db->query($sql);
213 //-- end new
214 }
215 else{
216 $tablename = $this->tablename;
217 }
218
219
220 $sql = sprintf("DELETE FROM %s WHERE token='%s'",
221 $tablename,
222 $token
223 );
224
225 $this->logger->write('debug', 'QUERY PURGE: ' . $sql);
226 $result = $this->db->query($sql);
227
228 // purge cache
229 if($this->cache !== false) {
230 $this->cache->delete('TOKEN_'.$token);
231 $this->logger->write('debug', 'CACHED PURGE KEY: TOKEN_'.$token);
232 }
233 return $result;
234 }
235
236 public function resetExpKeepsignin($token,$msisdn){
237
238 $token = $this->_escape($token);
239
240 //$tablename = $this->_getTablename($token);
241 if($this->_userTypeFromToken($token) == 'SUBSCRIBER'){
242 $a = explode('-', $token);
243 $index = $a[count($a)-1];
244 $tablename = $this->tablename . '_' . $index;
245 }
246 else{
247 $tablename = $this->tablename;
248 }
249
250 $expired = date('Y-m-d H:i:s', strtotime("+1 day"));
251 $sql = sprintf("UPDATE %s SET expired='%s' WHERE msisdn='%s' and token != '%s'",
252 $tablename,
253 $expired,
254 $msisdn,
255 $token
256 );
257
258 $this->logger->write('debug', 'QUERY RESET EXPIRED CHANGEPASSWORD: ' . $sql);
259 $result = (string) $this->db->query($sql);
260 $this->logger->write('debug', 'RESULT RESET EXPIRED CHANGEPASSWORD: ' . $result);
261
262 }
263
264 public function updateSessionExpired($token, $time=''){
265
266 $token = $this->_escape($token);
267
268 //$tablename = $this->_getTablename($token);
269 if($this->_userTypeFromToken($token) == 'SUBSCRIBER'){
270 $a = explode('-', $token);
271 $index = $a[count($a)-1];
272 $tablename = $this->tablename . '_' . $index;
273 }
274 else{
275 $tablename = $this->tablename;
276 }
277
278 // $expired = date('Y-m-d H:i:s', strtotime("+1 month"));
279 $expired = date('Y-m-d H:i:s');
280 $sql = sprintf("UPDATE %s SET expired='%s' WHERE token='%s'",
281 $tablename,
282 $expired,
283 $token
284 );
285
286 $this->logger->write('debug', 'QUERY INCREASE EXPIRED KEEP SIGNIN: ' . $sql);
287 $result = (string) $this->db->query($sql);
288 $this->logger->write('debug', 'RESULT INCREASE EXPIRED KEEP SIGNIN: ' . $result);
289
290 if($result != '0'){
291 return ($result == '-1') ? 'INVALID':true;
292 }
293 else{
294 return false;
295 }
296 }
297
298 public function create($userType, $session){
299
300 $param = $this->_escape(array(
301 'application_id' => $session->application_id,
302 'application_name' => $session->application_name,
303 'identity' => $session->identity,
304 'group_id' => $session->group_id,
305 'channel_id' => $session->channel_id,
306 'channel' => $session->channel,
307 'is_mobile' => $session->is_mobile,
308 'brand' => $session->brand,
309 'model' => $session->model,
310 'browser' => $session->browser,
311 'user_agent' => $session->user_agent,
312 'user_loc' => 0,
313 'ip' => $session->ip,
314 'onnet' => $session->onnet,
315 'msisdn_type' => $session->msisdn_type,
316 'imei' => $session->imei,
317 'xbox_package' => $session->xbox_package,
318 'xbox_hotoffer' => $session->xbox_hotoffer,
319 'query_balance' => json_encode($session->query_balance)
320 ));
321
322 $token = $this->_genToken($userType, $param['identity']);
323 if($session->keep_signin=="1" || $session->onnet=='1'){
324 $expired = date('Y-m-d H:i:s', strtotime("+1 month"));
325
326 //$expired = date('Y-m-d 12:30:s');
327 }else{
328 $expired = date('Y-m-d H:i:s', mktime(date('H'),(date('i')+20+(int)$this->config->app('session_expire')),date('s'),date('m'),date('d'),date('Y')));
329 }
330
331 $expired = date('Y-m-d H:i:s', strtotime("+1 month"));
332 if($userType == 'SUBSCRIBER'){
333 $tablename = $this->_getTablename($param['identity']);
334 $field = "msisdn";
335 }
336 else{
337 $tablename = $this->tablename;
338 $field = "user_name";
339 }
340// $this->purge_by_msisdn($param['identity'], $session->channel);
341 $sql = sprintf("INSERT INTO %s (
342 token,
343 application_id,
344 application_name,
345 %s,
346 group_id,
347 channel_id,
348 channel,
349 is_mobile,
350 brand,
351 model,
352 browser,
353 user_agent,
354 user_loc,
355 ip,
356 onnet,
357 msisdn_type,
358 imei,
359 xbox_package,
360 xbox_hotoffer,
361 query_balance,
362 created,
363 expired) VALUES (
364 '%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s',now(),'%s')",
365 $tablename,
366 $field,
367 $token,
368 $param['application_id'],
369 $param['application_name'],
370 $param['identity'],
371 $param['group_id'],
372 $param['channel_id'],
373 $param['channel'],
374 $param['is_mobile'],
375 $param['brand'],
376 $param['model'],
377 $param['browser'],
378 $param['user_agent'],
379 $param['user_loc'],
380 $param['ip'],
381 $param['onnet'],
382 $param['msisdn_type'],
383 $param['imei'],
384 $param['xbox_package'],
385 $param['xbox_hotoffer'],
386 $param['query_balance'],
387 $expired
388 );
389
390 $this->logger->write('debug', 'QUERY CREATE: ' . $sql);
391
392 if( $this->db->query($sql) ){
393 // cache it
394 if($this->cache !== false) {
395 $data = array_merge($param, array('expired' => $expired));
396 $this->cache->set('SESSION_'.$token, $data);
397 $this->logger->write('debug', 'CACHED KEY: SESSION_'.$token.' VALUE:'.print_r($data,1));
398 }
399 $this->logger->write('debug', 'RESULT CREATE: ' . $token);
400 return $token;
401 }
402 else{
403 return false;
404 }
405 }
406
407 /**
408 * get table name
409 * @param string $msisdn
410 */
411 private function _getTablename($msisdn){
412 $mod = $this->config->get('scaleTable');
413 return $this->tablename . '_' . ($msisdn%$mod);
414 }
415
416 public function checkPrivilege($token, $privilege){
417
418 $token = $this->_escape($token);
419
420 if( is_array($privilege) ){
421 $sqlPrivilege = "in ('" . implode("','", $privilege) . "')";
422 foreach($privilege as $row){
423 $return[$row] = false;
424 }
425 }
426 else{
427 $sqlPrivilege = "='$privilege'";
428 $return[$privilege] = false;
429 }
430
431 $this->logger->write('info', 'PRE PRIVILEGE: ' . print_r($return,1));
432
433 if($this->_userTypeFromToken($token) == 'SUBSCRIBER'){
434 $a = explode('-', $token);
435 $index = $a[count($a)-1];
436 $tableMapGroup = 'space_sso_map_groups_users_' . $index;
437 $tablename = $this->tablename . '_' . $index;
438 }
439 else{
440 $tableMapGroup = 'space_sso_map_groups_users';
441 $tablename = $this->tablename;
442 }
443
444 $sql = sprintf("
445 SELECT
446 b.privilege_name,
447 a.brand, a.model,
448 a.user_loc,
449 a.onnet
450 FROM
451 %s a
452 LEFT JOIN
453 space_sso_map_applications_privileges b
454 ON
455 a.application_id=b.application_id AND a.group_id=b.group_id
456 WHERE
457 a.token='%s'
458 AND
459 b.privilege_name %s",
460 $tablename,
461 $token,
462 $sqlPrivilege
463 );
464
465 $this->logger->write('debug', 'QUERY CHECK_PRIVILEGE: ' . $sql);
466 $result = $this->db->fetch($sql);
467
468 if( $result ){
469 $this->logger->write('debug', 'RESULT CHECK_PRIVILEGE: ' . print_r($result,1));
470 foreach($result as $row) {
471 if( isset($return[$row['privilege_name']]) ) $return[$row['privilege_name']] = true;
472 }
473
474 $this->logger->write('info', 'FINAL PRIVILEGE: ' . print_r($return,1));
475
476 return array(
477 'privilege' => $return,
478 'brand' => $result[0]['brand'],
479 'model' => $result[0]['model'],
480 'user_loc' => $result[0]['user_loc'],
481 'onnet' => $result[0]['onnet']
482 );
483 //return $return;
484 }
485 else{
486 if( $this->db->affectedRows() == 0 ){
487 return array(
488 'privilege' => $return,
489 'brand' => '',
490 'model' => '',
491 'user_loc' => '',
492 'onnet' => ''
493 );
494 }
495 else{
496 return false;
497 }
498 }
499 }
500
501 /**
502 * get user from token
503 *
504 * @param string $token
505 * return int user id
506 */
507 public function getUserFromToken($token) {
508
509 $token = $this->_escape($token);
510
511 if( $this->_userTypeFromToken($token) == 'SUBSCRIBER' ){
512 $a = explode('-', $token);
513 $index = $a[count($a)-1];
514 $tablename = $this->tablename . '_' . $index;
515 $tableUser = 'space_sso_users_' . $index;
516 $sqlWhere = 'a.msisdn=b.msisdn';
517 }
518 else{
519 $tablename = $this->tablename;
520 $tableUser = 'space_sso_users';
521 $sqlWhere = 'a.name=b.user_name';
522 }
523
524 /*$sql = sprintf("SELECT
525 a.id,a.name,a.full_name,a.msisdn,a.email,a.language,a.location,a.regional,a.status, b.channel, b.group_id,b.application_name,
526 a.address,a.address2,a.address3,a.city,a.postcode,a.confirm_email,a.email_notify,a.push_notify,
527 a.gender,date_format(date(a.birth),'%d-%m-%Y') as birth
528 FROM
529 %s a
530 LEFT JOIN
531 %s b
532 ON
533 %s
534 WHERE token='%s'",
535 $tableUser,
536 $tablename,
537 $sqlWhere,
538 $token
539 );*/
540
541 $sql = "SELECT
542 a.id,a.name,a.full_name,a.msisdn,a.msisdn_type,a.email,a.language,a.location,a.regional,a.status, b.channel, b.group_id,b.application_name,
543 a.address,a.address2,a.address3,a.city,a.postcode,a.confirm_email,a.email_notify,a.push_notify,a.gender,a.browser,a.fb_user,a.fb_token,
544 a.idcard_type, a.nik_number, a.kk_number, a.mothers_name, a.validated, a.place_birth, a.other_phone,
545 IFNULL(IF(a.birth='0000-00-00 00:00:00',null,date_format(date(a.birth),'%d-%m-%Y')),'') birth,
546 b.imei,b.xbox_package,b.xbox_hotoffer,b.query_balance
547 FROM
548 ".$tableUser." a
549 LEFT JOIN
550 ".$tablename." b
551 ON
552 ".$sqlWhere."
553 WHERE token='".$token."'";
554
555 $this->logger->write('debug', 'QUERY GET_MSISDN_FROM_TOKEN: ' . $sql);
556 $result = $this->db->fetchOne($sql);
557 $this->logger->write('debug', 'RESULT GET_MSISDN_FROM_TOKEN: ' . print_r($result,1));
558 return $result;
559 }
560
561 /**
562 * generate token
563 * @param unknown_type $msisdn
564 */
565 private function _genToken($userType, $identity){
566 if(isset($_SERVER['SERVER_ADDR'])){
567 if( strpos($_SERVER['SERVER_ADDR'], ',') !== false ){
568 $sandbox = explode(',', $_SERVER['SERVER_ADDR']);
569 $ip = ip2long($sandbox[count($sandbox)-1]);
570 }
571 else{
572 $ip = ip2long($_SERVER['SERVER_ADDR']);
573 }
574 }
575 else{
576 $ip = '';
577 }
578
579 $shard = ($ip == '') ? uniqid():$ip.'_'.substr(uniqid(),-5).rand(1,999);
580
581 if($userType == 'SUBSCRIBER'){
582 $mod = $this->config->get('scaleTable');
583 $index = ($identity%$mod);
584 return $shard . rand(0,999) . '-' . $index;
585 }
586 else{
587 return $shard . rand(0,999) . $this->_randStr(1);
588 }
589 }
590
591 /**
592 * user type from token
593 * @param string $token
594 */
595 private function _userTypeFromToken($token){
596 if( ctype_digit(substr($token,-1)) ){
597 return 'SUBSCRIBER';
598 }
599 else{
600 return 'STAFF';
601 }
602 }
603
604 /**
605 * generate random string
606 * @param int $length
607 */
608 private function _randStr($length=8){
609 // makes a random alpha numeric string of a given lenth
610 $str = range('a', 'z');
611 $out ='';
612 for($c=0;$c < $length;$c++) {
613 $out .= $str[mt_rand(0,count($str)-1)];
614 }
615 return $out;
616 }
617
618 public function increaseExpired($token, $time=''){
619
620 $token = $this->_escape($token);
621
622 //$tablename = $this->_getTablename($token);
623 if($this->_userTypeFromToken($token) == 'SUBSCRIBER'){
624 $a = explode('-', $token);
625 $index = $a[count($a)-1];
626 $tablename = $this->tablename . '_' . $index;
627 }
628 else{
629 $tablename = $this->tablename;
630 }
631 if( $time=='' ){
632 $interval = 10;
633 }
634 else{
635 $interval = $time;
636 }
637
638 $sql = sprintf("UPDATE %s SET expired=DATE_ADD(expired,INTERVAL %d MINUTE) WHERE token='%s'",
639 $tablename,
640 $interval,
641 $token
642 );
643
644 $this->logger->write('debug', 'QUERY INCREASE EXPIRED: ' . $sql);
645 $result = (string) $this->db->query($sql);
646 $this->logger->write('debug', 'RESULT INCREASE EXPIRED: ' . $result);
647
648 if($result != '0'){
649 return ($result == '-1') ? 'INVALID':true;
650 }
651 else{
652 return false;
653 }
654 }
655
656 function purge_by_msisdn($msisdn, $channel = '')
657 {
658 $tablename = $this->_getTablename($msisdn);
659 $sql = sprintf("DELETE FROM %s WHERE msisdn = '%s' and channel = '%s'",
660 $tablename,
661 $msisdn,
662 $channel
663 );
664
665 $this->logger->write('debug', 'QUERY PURGE BY MSISDN: ' . $sql);
666 // $result = $this->db->query($sql);
667 }
668
669}