BAOBAB
co_security_login.class.php
Go to the documentation of this file.
1 <?php
2 /***************************************************************************************************************************/
26 defined( 'LGV_DBF_CATCHER' ) or die ( 'Cannot Execute Directly' ); // Makes sure that this file is in the correct context.
27 
28 if ( !defined('LGV_SDBN_CATCHER') ) {
29  define('LGV_SDBN_CATCHER', 1);
30 }
31 
32 require_once(CO_Config::db_class_dir().'/co_security_node.class.php');
33 
34 /***************************************************************************************************************************/
40  protected $_api_key;
41  protected $_personal_ids;
42  protected $_ids;
43 
44  var $login_id;
45 
46  /***********************/
52  protected static function _random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
53  {
54  $pieces = [];
55  $max = mb_strlen($keyspace, '8bit') - 1;
56  for ($i = 0; $i < $length; ++$i) {
57  $pieces []= $keyspace[random_int(0, $max)];
58  }
59  return implode('', $pieces);
60  }
61 
62  /***********************/
66  protected function _set_up_api_key( $key_length
67  ) {
68  $temp_api_key = self::_random_str($key_length);
69 
70  $temp_api_key .= ' - '.strval(microtime(true)); // Add the current generation microtime, for key timeout.
71 
72  // If we are taking the IP address into consideration, then we store that, as well.
73  if (isset(CO_Config::$api_key_includes_ip_address) && CO_Config::$api_key_includes_ip_address) {
74  $temp_api_key .= ' - '.strtolower(strval($_SERVER['REMOTE_ADDR']));
75  }
76 
77  $this->_api_key = strval($temp_api_key);
78  }
79 
80  /***********************************************************************************************************************/
81  /***********************/
91  protected function _default_setup() {
92  $default_setup = parent::_default_setup();
93  $default_setup['login_id'] = $this->login_id;
94  $default_setup['object_name'] = $this->login_id;
95  $default_setup['api_key'] = $this->_api_key;
96  $default_setup['personal_ids'] = (CO_Config::use_personal_tokens() && (NULL != $this->_personal_ids)) ? $this->_personal_ids : '';
97  $default_setup['ids'] = (NULL != $this->_ids) ? $this->_ids : '';
98 
99  return $default_setup;
100  }
101 
102  /***********************/
110  protected function _build_parameter_array() {
111  $ret = parent::_build_parameter_array();
112 
113  if (NULL == $this->_personal_ids) {
114  $this->_personal_ids = [];
115  }
116 
117  $ret['api_key'] = $this->_api_key;
118  $ret['login_id'] = $this->login_id;
119  $personal_ids_as_string_array = Array();
120  if (CO_Config::use_personal_tokens()) {
121  $personal_ids_as_int = array_map('intval', $this->_personal_ids);
122  sort($personal_ids_as_int);
123 
124  foreach ($this->_personal_ids as $id) {
125  array_push($personal_ids_as_string_array, strval($id));
126  }
127 
128  $personal_id_list_string = trim(implode(',', $personal_ids_as_string_array));
129  $ret['personal_ids'] = $personal_id_list_string ? $personal_id_list_string : NULL;
130  }
131 
132  $ids_as_int = array_map('intval', $this->_ids);
133  sort($ids_as_int);
134 
135  $ids_as_string_array = Array();
136  foreach ($this->_ids as $id) {
137  if ($id != $this->id() && (isset($personal_ids_as_int) && !in_array($id, $personal_ids_as_int))) {
138  array_push($ids_as_string_array, strval($id));
139  } elseif ($id != $this->id()) {
140  array_push($ids_as_string_array, strval($id));
141  }
142  }
143 
144  $id_list_string = trim(implode(',', $ids_as_string_array));
145 
146  $ret['ids'] = $id_list_string ? $id_list_string : NULL;
147 
148  if ($this->_override_access_class) {
149  $ret['access_class'] = 'CO_Security_ID';
150  $ret['object_name'] = NULL;
151  $ret['ids'] = NULL;
152  $this->context = NULL;
153  $this->_override_access_class = false;
154  }
155 
156  return $ret;
157  }
158 
159  /***********************************************************************************************************************/
160  /***********************/
164  public function __construct( $in_db_object = NULL,
165  $in_db_result = NULL,
166  $in_login_id = NULL,
167  $in_ids = NULL,
168  $in_personal_ids = NULL
169  ) {
170  $this->login_id = $in_login_id;
171  $this->_override_access_class = false;
172  parent::__construct($in_db_object, $in_db_result, $in_ids);
173  $this->class_description = 'This is a security class for individual logins.';
174 
175  // If explicit IDs are passed in, then that overrides the DB.
176  if (isset($in_ids) && is_array($in_ids) && count($in_ids)) {
177  $in_db_result['ids'] = implode(',', $in_ids);
178  }
179 
180  if (CO_Config::use_personal_tokens() && isset($in_personal_ids) && is_array($in_personal_ids) && count($in_personal_ids)) {
181  $in_db_result['personal_ids'] = implode(',', $in_ids);
182  }
183 
184  if (!isset($this->context)) {
185  $this->context = Array();
186  }
187 
188  if (!isset($this->context['lang'])) {
189  $this->context['lang'] = CO_Config::$lang;
190  }
191 
192  if (isset($in_db_result['api_key'])) {
193  $this->_api_key = $in_db_result['api_key'];
194  }
195 
196  if (intval($this->id()) == intval(CO_Config::god_mode_id())) {
197  // God Mode is always forced to use the config password.
198  $this->instance_description = 'GOD MODE: '.(isset($this->name) && $this->name ? "$this->name (".$this->login_id.")" : "Unnamed Login Node (".$this->login_id.")");
199  } else {
200  $this->instance_description = isset($this->name) && $this->name ? "$this->name (".$this->login_id.")" : "Unnamed Login Node (".$this->login_id.")";
201  }
202 
203  $access_object = $this->get_access_object();
204 
205  // By now, we have enough read, so we know if cogito ergo sum, so we can see if we can look at the IDs.
206  if (isset($access_object) && ($access_object->god_mode() || ($access_object->get_login_id() == $this->_id))) {
207  $this->_ids = Array($this->id());
208 
209  if (isset($in_db_result['ids']) && $in_db_result['ids']) {
210  $temp = $in_db_result['ids'];
211  if (isset ($temp) && $temp) {
212  $tempAr = explode(',', $temp);
213  if (is_array($tempAr) && count($tempAr)) {
214  $tempAr = array_unique(array_map('intval', $tempAr));
215  $tempAr = array_merge($this->_ids, $tempAr);
216  sort($tempAr);
217  // Our original login just gets all the IDs. However, subsequent access requires that only "known" IDs are read.
218  if (isset($tempAr) && is_array($tempAr) && count($tempAr)) {
219  $access_ids = $access_object->get_security_ids();
220  if ($access_object->god_mode() || (isset($access_ids) && is_array($access_ids) && count($access_ids))) {
221  foreach($tempAr as $id) {
222  if (($access_object->god_mode() || (in_array($id, $access_ids))) && !in_array($id, $this->_ids)) {
223  $this->_ids[] = $id;
224  }
225  }
226  } else {
227  $this->_ids = $tempAr;
228  }
229  }
230  }
231  }
232  }
233 
234  $this->_personal_ids = NULL;
235 
236  if (CO_Config::use_personal_tokens() && isset($in_db_result['personal_ids']) && $in_db_result['personal_ids']) {
237  $temp = $in_db_result['personal_ids'];
238  if (isset ($temp) && $temp) {
239  $tempAr = explode(',', $temp);
240  if (is_array($tempAr) && count($tempAr)) {
241  $tempAr = array_unique(array_map('intval', $tempAr));
242  sort($tempAr);
243  if (isset($tempAr) && is_array($tempAr) && count($tempAr)) {
244  $this->_personal_ids = $tempAr;
245  }
246  }
247  }
248  }
249  }
250  }
251 
252  /***********************/
258  public function load_from_db($in_db_result) {
259  $ret = parent::load_from_db($in_db_result);
260  $this->_personal_ids = NULL;
261  $this->_ids = Array($this->id());
262 
263  if ($ret) {
264  if (!isset($this->context)) {
265  $this->context = Array();
266  }
267 
268  if (!isset($this->context['lang'])) {
269  $this->context['lang'] = CO_Config::$lang;
270  }
271 
272  $this->class_description = 'This is a security class for individual logins.';
273 
274  if (isset($in_db_result['login_id'])) {
275  $this->login_id = $in_db_result['login_id'];
276  $this->instance_description = isset($this->name) && $this->name ? "$this->name (".$this->login_id.")" : "Unnamed Login Node (".$this->login_id.")";
277  }
278 
279  if (isset($in_db_result['api_key'])) {
280  $this->_api_key = $in_db_result['api_key'];
281  }
282 
283  if (isset($in_db_result['ids']) && $in_db_result['ids']) {
284  if ($this->_db_object) {
285  if (isset($in_db_result['ids']) && $in_db_result['ids']) {
286  $temp = $in_db_result['ids'];
287  if (isset ($temp) && $temp) {
288  $tempAr = explode(',', $temp);
289  if (is_array($tempAr) && count($tempAr)) {
290  $tempAr = array_map('intval', $tempAr);
291  sort($tempAr);
292  $tempAr = array_unique(array_merge($this->_ids, $tempAr));
293  if (isset($tempAr) && is_array($tempAr) && count($tempAr)) {
294  $this->_ids = $tempAr;
295  }
296  }
297  }
298  }
299  }
300  }
301 
302  if (CO_Config::use_personal_tokens() && isset($in_db_result['personal_ids']) || isset($in_db_result['personal_ids'])) {
303  $temp = $in_db_result['personal_ids'];
304  if (isset ($temp) && $temp) {
305  $tempAr = explode(',', $temp);
306  if (is_array($tempAr) && count($tempAr)) {
307  $tempAr = array_unique(array_map('intval', $tempAr));
308  sort($tempAr);
309  if (isset($tempAr) && is_array($tempAr) && count($tempAr)) {
310  $this->_personal_ids = $tempAr;
311  }
312  }
313  }
314  }
315  }
316 
317  return $ret;
318  }
319 
320  /***********************/
328  public function set_ids( $in_ids_array
329  ) {
330  $ret = false;
331  $in_ids_array = array_map('intval', $in_ids_array);
332  if ($this->user_can_edit_ids()) {
333  $id_pool = $this->get_access_object()->get_security_ids(true); // We get just our regular IDs. No personal ones.
334  if ($this->get_access_object()->god_mode() || (isset($id_pool) && is_array($id_pool) && count($id_pool))) {
335  // First thing we do, is ensure that EVERY SINGLE ID in the current user are ones we have in our own set.
336  // An empty set is fine.
337  foreach($this->_ids as $id) {
338  if (!$this->get_access_object()->god_mode() && (isset($id) && (0 < $id) && !in_array($id, $id_pool))) {
339  // Even one failure scrags the operation.
343  __LINE__,
344  __FILE__,
345  __METHOD__
346  );
347  return false;
348  }
349  }
350 
351  // Next, if there is an existing array, we check our input, and add only the IDs we own.
352  if ($this->get_access_object()->god_mode() || (isset($in_ids_array) && is_array($in_ids_array) && count($in_ids_array))) {
353  $temp_ids = array_map('intval', $in_ids_array);
354  $new_ids = Array();
355  foreach($temp_ids as $in_id) {
356  if (($in_id != $this->id()) && ($this->get_access_object()->god_mode() || in_array($in_id, $id_pool))) {
357  $new_ids[] = $in_id;
358  }
359  }
360 
361  $this->_ids = $new_ids;
362  // Otherwise, we are clearing the array.
363  } else {
364  $this->_ids = Array();
365  }
366 
367  $ret = $this->update_db();
368  } else {
372  __LINE__,
373  __FILE__,
374  __METHOD__
375  );
376  }
377  } else {
381  __LINE__,
382  __FILE__,
383  __METHOD__
384  );
385  }
386 
387  return $ret;
388  }
389 
390  /***********************/
396  public function add_id( $in_id
397  ) {
398  $ret = false;
399  $in_id = intval($in_id);
400  if ($this->user_can_edit_ids() || ($this->_added_new_id == $in_id)) {
401  $id_pool = $this->get_access_object()->get_security_ids(true);
402 
403  if ($this->get_access_object()->god_mode() || (isset($id_pool) && is_array($id_pool) && count($id_pool))) {
404  // We can add an ID to the user, as long as it is one we own. We don't have to have full access to all user IDs.
405  if (($this->get_access_object()->god_mode() || (in_array($in_id, $id_pool)) || ($this->_added_new_id == $in_id)) && ($in_id != $this->id())) {
406  if (!isset($this->_ids) || !is_array($this->_ids) || !count($this->_ids)) {
407  $this->_ids = Array(intval($in_id));
408  } else {
409  $this->_ids[] = $in_id;
410  $this->_ids = array_unique($this->_ids);
411  }
412  sort($this->_ids);
413  $ret = $this->update_db();
414  } else {
415  if ($in_id != $this->id()) {
419  __LINE__,
420  __FILE__,
421  __METHOD__
422  );
423  } else { // If we tried to add our own ID, then we don't add it, but it's not an error.
424  $ret = true;
425  }
426  }
427  }
428  } else {
432  __LINE__,
433  __FILE__,
434  __METHOD__
435  );
436  }
437 
438  return $ret;
439  }
440 
441  /***********************/
448  public function remove_id( $in_id
449  ) {
450  $ret = false;
451 
452  if ($this->user_can_edit_ids()) {
453  $id_pool = $this->get_access_object()->get_security_ids();
454 
455  if ($this->get_access_object()->god_mode() || (isset($id_pool) && is_array($id_pool) && count($id_pool) && in_array($in_id, $id_pool))) {
456  if (isset($this->_ids) && is_array($this->_ids) && count($this->_ids) && $this->user_can_edit_ids()) {
457  $new_array = Array();
458 
459  foreach($this->_ids as $id) {
460  if ($id != $in_id) {
461  array_push($new_array, $id);
462  } else {
463  $ret = true;
464  }
465 
466  if ($ret) {
467  $ret = $this->set_ids($new_array);
468  }
469  }
470  }
471  } else {
475  __LINE__,
476  __FILE__,
477  __METHOD__
478  );
479  }
480  } else {
484  __LINE__,
485  __FILE__,
486  __METHOD__
487  );
488  }
489 
490  return $ret;
491  }
492 
493  /***********************/
499  public function ids() {
500  if ($this->get_access_object()->god_mode()) {
501  return $this->_ids;
502  } else {
503  $my_ids = $this->get_access_object()->get_security_ids();
504  $ret = Array();
505  foreach ($this->_ids as $id) {
506  if (in_array($id, $my_ids)) {
507  array_push($ret, $id);
508  }
509  }
510  return $ret;
511  }
512  }
513 
514  /***********************/
522  public function user_can_edit_ids() {
523  $ret = ($this->get_access_object()->get_login_id() != $this->_id) && ($this->get_access_object()->god_mode() || $this->_db_object->i_have_all_ids($this->_id));
524 
525  return $ret;
526  }
527 
528  /***********************/
538  public function set_personal_ids( $in_personal_ids = []
539  ) {
540  $personal_ids_temp = array_unique(array_map('intval', $in_personal_ids));
541  $this->_personal_ids = [];
542  $access_object = $this->get_access_object();
543 
544  if (CO_Config::use_personal_tokens() && isset($access_object) && $access_object->god_mode()) {
545  if (0 < count($personal_ids_temp)) {
546  $personal_ids = [];
547  $my_ids = $this->_ids;
548  // None of the ids can be in the regular IDs, and will be removed from the set, if so.
549  // They also cannot be anyone else's personal ID, or anyone's login ID. Personal IDs can ONLY be regular (non-login) security objects.
550  foreach($personal_ids_temp as $id) {
551  // Make sure that we don't have this personal token in our regular ID array.
552  if (($key = array_search($id, $my_ids)) !== false) {
553  unset($my_ids[$key]);
554  }
555  if (!$this->get_access_object()->is_this_a_login_id($id) || in_array($id, $this->_personal_ids)) {
556  array_push($personal_ids, $id);
557  }
558  }
559  $this->_ids = $my_ids;
560  sort($personal_ids);
561  $this->_personal_ids = $personal_ids;
562  }
563  }
564 
565  $this->update_db();
566 
567  return $this->_personal_ids;
568  }
569 
570  /***********************/
576  public function personal_ids() {
577  if (!CO_Config::use_personal_tokens()) {
578  return [];
579  }
580 
581  if ($this->get_access_object()->god_mode()) {
582  return $this->_personal_ids;
583  } else {
584  $my_ids = $this->get_access_object()->get_security_ids();
585  $ret = [];
586  if (isset($this->_personal_ids) && is_array($this->_personal_ids) && count($this->_personal_ids)) {
587  foreach ($this->_personal_ids as $id) {
588  if (in_array($id, $my_ids)) {
589  array_push($ret, $id);
590  }
591  }
592  }
593  return $ret;
594  }
595  }
596 
597  /***********************/
601  public function get_crypted_password( $in_password_to_crypt = NULL
602  ) {
603 
604  $ret = $this->context['hashed_password'];
605 
606  if ($in_password_to_crypt) {
607  if (strlen($in_password_to_crypt) >= CO_Config::$min_pw_len) {
608  $ret = password_hash($in_password_to_crypt, PASSWORD_DEFAULT);
609  } else {
610  $ret = false;
611  }
612  }
613 
614  return $ret;
615  }
616 
617  /***********************/
621  public function is_login_valid( $in_login_id,
622  $in_hashed_password = NULL,
623  $in_raw_password = NULL,
624  $in_dont_create_new_api_key = false
625  ) {
626  $ret = false;
627  if (isset($this->login_id) && $this->login_id && ($this->login_id == $in_login_id)) {
628  $api_key = $this->get_api_key();
629  if ($this->id() == CO_Config::god_mode_id()) {
630  if (("" != $in_hashed_password) && ($in_hashed_password == $api_key)) { // We have a special provision that allows the God hashed password to use the API key.
631  $ret = true;
632  } else { // God mode uses the cleartext password in the config file.
633  if ($in_raw_password && !$in_dont_create_new_api_key && isset(CO_Config::$block_logins_for_valid_api_key) && CO_Config::$block_logins_for_valid_api_key && $api_key) {
634  return false;
635  } else {
636  $ret = ($in_raw_password == CO_Config::god_mode_password());
637  }
638  }
639  } else {
640  // The server can be set up to prevent users from logging in while another login is still active.
641  if ($in_raw_password && !$in_dont_create_new_api_key && isset(CO_Config::$block_logins_for_valid_api_key) && CO_Config::$block_logins_for_valid_api_key && $api_key) {
642  return false;
643  } elseif (isset($this->context['hashed_password']) && $this->context['hashed_password']) {
644  // First, see if this is in the hashed password.
645  if ($in_hashed_password) {
646  $ret = hash_equals($this->get_crypted_password(), $in_hashed_password);
647  } else { // If not, see if it's the raw password.
648  $ret = password_verify($in_raw_password, $this->get_crypted_password());
649  }
650  }
651  }
652  }
653 
654  // Generate an API key. We can't save it yet, as we're probably not actually logged in.
655  if ($ret && !$in_dont_create_new_api_key) {
656  // God mode gets a longer key. It's not actually more secure, but we can use that to determine different treatment, later on.
657  $this->_set_up_api_key($this->id() == CO_Config::god_mode_id() ? 40 : 32);
658  }
659 
660  return $ret;
661  }
662 
663  /***********************/
667  public function i_am_a_god() {
668  return intval(CO_Config::god_mode_id()) == intval($this->id());
669  }
670 
671  /***********************/
675  public function is_god() {
676  return $this->id() == CO_Config::god_mode_id();
677  }
678 
679  /***********************/
683  public function is_manager() {
684  return $this->is_god();
685  }
686 
687  /***********************/
691  public function get_lang() {
692  return $this->context['lang'];
693  }
694 
695  /***********************/
699  public function set_lang( $in_lang_id = NULL
700  ) {
701  $ret = false;
702 
703  if ($this->user_can_write()) {
704  $this->context['lang'] = strtolower(trim(strval($in_lang_id)));
705  $ret = $this->update_db();
706  }
707 
708  return $ret;
709  }
710 
711  /***********************/
715  public function get_user_object() {
716  $ret = NULL;
717  $access_instance = $this->get_access_object();
718 
719  // If we have a user, we also clear the user from knowing about us.
720  if ($access_instance && method_exists($access_instance, 'get_user_from_login')) {
721  $ret = $access_instance->get_user_from_login($this->id());
722  }
723 
724  return $ret;
725  }
726 
727  /***********************/
733  public function set_password_from_cleartext( $in_cleartext_password
734  ) {
735  $ret = false;
736 
737  if ($this->user_can_write()) {
738  $this->context['hashed_password'] = $this->get_crypted_password($in_cleartext_password);
739  $ret = $this->update_db();
740  }
741 
742  return $ret;
743  }
744 
745  /***********************/
751  public function is_api_key_valid( $in_api_key
752  ) {
753  $ret = ($this->get_api_key() == $in_api_key);
754 
755  if ($ret && !$this->error) {
759  );
760  }
761 
762  return $ret;
763  }
764 
765  /***********************/
769  public function get_remaining_time() {
770  $ret = 0;
771 
772  // Unless we are legally logged in, we will always get 0.
773  if ( $this->get_api_key() ) {
774  $timeout = floatval($this->i_am_a_god() ? CO_Config::$god_session_timeout_in_seconds : CO_Config::$session_timeout_in_seconds);
775 
776  if ( 0 < $timeout ) {
777  if (isset($this->_api_key) && $this->_api_key) {
778  list($api_key, $api_time) = explode(' - ', trim($this->_api_key));
779  $ret = $timeout - ceil((microtime(true) - floatval($api_time)) * 10000) / 10000;
780  }
781  } else {
782  $ret = -1;
783  }
784  }
785 
786  return $ret;
787  }
788 
789  /***********************/
793  public function get_api_key() {
794  $ret = NULL;
795 
796  if (isset($this->_api_key) && $this->_api_key) {
797  $api_expl = explode(' - ', trim($this->_api_key));
798  $my_ip = NULL;
799 
800  // God Mode gets a different timeout.
801  $timeout = floatval($this->i_am_a_god() ? CO_Config::$god_session_timeout_in_seconds : CO_Config::$session_timeout_in_seconds);
802 
803  // We first check to make sure that we are still within the time window. If not, then all bets are off.
804  // <0 as a $timeout value means no timeout.
805  if (isset($api_expl[1]) && ((0 > $timeout) || ((microtime(true) - floatval($api_expl[1])) <= $timeout))) {
806  if (isset(CO_Config::$api_key_includes_ip_address) && CO_Config::$api_key_includes_ip_address) { // See if we are also checking the IP address.
807  $my_ip = strtolower(strval($_SERVER['REMOTE_ADDR']));
808  if (isset($api_expl[2])) {
809  if ($api_expl[2] == $my_ip) {
810  $ret = $api_expl[0];
811  } else {
815  );
816  }
817  } else {
821  );
822  }
823  } else {
824  $ret = $api_expl[0];
825  }
826  } elseif ($api_expl[0]) {
830  );
831  }
832  }
833 
834  return $ret;
835  }
836 
837  /***********************/
842  $ret = -1;
843 
844  if (isset($this->_api_key) && $this->_api_key) {
845  list($api_key, $api_time) = explode(' - ', trim($this->_api_key));
846  $ret = ceil(microtime(true) - floatval($api_time));
847  }
848 
849  return $ret;
850  }
851 
852  /***********************/
858  public function clear_api_key() {
859  $this->_api_key = NULL;
860 
861  return $this->update_db();
862  }
863 
864  /***********************/
870  public function add_personal_token_from_current_login( $in_id
871  ) {
872  $ret = $this->get_access_object()->add_personal_token_from_current_login($this->_id, $in_id);
873 
874  if ($this->get_access_object()->error) {
875  $this->error = $this->get_access_object()->error;
876  } else {
877  $this->reload_from_db();
878  return $ret;
879  }
880 
881  return false;
882  }
883 
884  /***********************/
890  public function remove_personal_token_from_this_login( $in_id
891  ) {
892  $ret = $this->get_access_object()->remove_personal_token_from_this_login($this->_id, $in_id);
893 
894  if ($this->get_access_object()->error) {
895  $this->error = $this->get_access_object()->error;
896  } else {
897  $this->reload_from_db();
898  return $ret;
899  }
900 
901  return false;
902  }
903 
904  /***********************/
911  return $this->get_access_object()->get_logins_that_have_any_of_my_ids();
912  }
913 
914  /***********************/
920  public function user_can_write() {
921  $ret = false;
922 
923  // Only God can edit God.
924  if ($this->i_am_a_god() && !$this->get_access_object()->god_mode()) {
925  return false;
926  } else {
927  $ids = $this->get_access_object()->get_security_ids();
928 
929  $my_write_item = intval($this->write_security_id);
930 
931  if ((0 == $my_write_item) || $this->get_access_object()->god_mode()) {
932  $ret = true;
933  } else {
934  if (isset($ids) && is_array($ids) && count($ids)) {
935  $ret = in_array($my_write_item, $ids);
936  }
937  }
938 
939  return $ret;
940  }
941  }
942 
943  /***********************/
949  public function delete_from_db() {
950  if ($this->id() != CO_Config::god_mode_id()) {
951  if ($this->user_can_write()) {
952  $user_object = $this->get_user_object();
953 
954  if (isset($user_object) && ($user_object instanceof CO_User_Collection)) {
955  $user_object->set_login(NULL);
956  }
957 
958  $this->read_security_id = 0;
959  $this->write_security_id = -1;
960  $this->api_key = NULL;
961  $this->context = NULL;
962  $this->name = NULL;
963  $this->login_id = NULL;
964  $this->_ids = Array();
965  $this->_override_access_class = true;
966  $ret = $this->_write_to_db();
967  return $ret;
968  } else {
969  return false;
970  }
971  } else {
975  );
976  }
977  }
978 };
if(!defined( 'LGV_SDBN_CATCHER'))
$_id
This is the within-table unique ID of this record.
set_lang( $in_lang_id=NULL)
$_api_key
This is an API key for REST.
$_personal_ids
These are personal IDs (special IDs, unique to the login).
is_login_valid( $in_login_id, $in_hashed_password=NULL, $in_raw_password=NULL, $in_dont_create_new_api_key=false)
get_crypted_password( $in_password_to_crypt=NULL)
$_ids
These are security tokens, available to this ID.
add_personal_token_from_current_login( $in_id)
remove_personal_token_from_this_login( $in_id)
set_personal_ids( $in_personal_ids=[])
$_override_access_class
This is a special "one-shot" semaphore telling the save to override the access class.
set_password_from_cleartext( $in_cleartext_password)
__construct( $in_db_object=NULL, $in_db_result=NULL, $in_login_id=NULL, $in_ids=NULL, $in_personal_ids=NULL)
static _random_str($length, $keyspace='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
static $login_error_code_attempt_to_delete_god
Definition: common.inc.php:60
static $login_error_code_api_key_mismatch
Definition: common.inc.php:58
static $db_error_code_user_not_authorized
Definition: common.inc.php:51
static $login_error_code_api_key_invalid
Definition: common.inc.php:57
static $db_error_name_user_not_authorized
Definition: en.php:55
static $db_error_desc_user_not_authorized
Definition: en.php:56
static $login_error_name_attempt_to_delete_god
Definition: en.php:70
static $login_error_desc_attempt_to_delete_god
Definition: en.php:71
static $login_error_desc_api_key_mismatch
Definition: en.php:68
static $login_error_name_api_key_invalid
Definition: en.php:65
static $login_error_name_api_key_mismatch
Definition: en.php:67
static $login_error_desc_api_key_invalid
Definition: en.php:66
This class provides a general error report, with file, method and error information.
Definition: error.class.php:32