BAOBAB
co_people_basalt_plugin.class.php
Go to the documentation of this file.
1 <?php
2 /***************************************************************************************************************************/
27 defined( 'LGV_BASALT_CATCHER' ) or die ( 'Cannot Execute Directly' ); // Makes sure that this file is in the correct context.
28 
29 /****************************************************************************************************************************/
34  /***********************/
40  protected function _get_short_description( $in_object,
41  $in_additional_info = false
42  ) {
43  $ret = parent::_get_short_description($in_object, $in_additional_info);
44 
45  if ($in_object instanceof CO_Security_Login) {
46  $ret['login_id'] = $in_object->login_id;
47  }
48 
49  return $ret;
50  }
51 
52  /***********************/
58  protected function _get_long_description( $in_login_object,
59  $ignored = false
60  ) {
61  $ret = parent::_get_long_description($in_login_object);
62 
63  $user_item = $in_login_object->get_user_object();
64 
65  if ($in_login_object->id() == $in_login_object->get_access_object()->get_login_id()) {
66  $ret['current_login'] = true;
67  }
68 
69  if (isset($user_item) && ($user_item instanceof CO_User_Collection)) {
70  $ret['user_object_id'] = $user_item->id();
71  }
72 
73  $ret['login_id'] = $in_login_object->login_id;
74  $ret['is_manager'] = $in_login_object->is_manager();
75  $ret['is_main_admin'] = $in_login_object->is_god();
76  $security_tokens = $in_login_object->get_access_object()->god_mode() && $in_login_object->is_god() ? $in_login_object->get_access_object()->get_all_tokens() : $in_login_object->ids();
77  if (isset($security_tokens) && is_array($security_tokens) && count($security_tokens)) {
78  $ret['security_tokens'] = $security_tokens;
79  }
80  $personal_tokens = $in_login_object->personal_ids();
81  if (isset($personal_tokens) && is_array($personal_tokens) && count($personal_tokens)) {
82  $ret['personal_tokens'] = $personal_tokens;
83  }
84 
85  $api_key = $in_login_object->get_api_key();
86  $key_age = $in_login_object->get_api_key_age_in_seconds();
87 
88  if ($api_key) {
89  // Most people can see whether or not the user has a current API key.
90  $ret['current_api_key'] = true;
91  // God can see the key, itself.
92  if ($in_login_object->get_access_object()->god_mode()) {
93  $ret['api_key'] = $api_key;
94  //...and how old it is.
95  if ( 0 <= $key_age) {
96  $ret['api_key_age_in_seconds'] = $key_age;
97  }
98  }
99  }
100 
101  return $ret;
102  }
103 
104  /***********************/
110  protected function _get_long_user_description( $in_user_object,
111  $in_with_login_info = false,
112  $in_show_parents = false
113  ) {
114  $ret = parent::_get_long_description($in_user_object, $in_show_parents);
115 
116  $test_string = $in_user_object->get_surname();
117  if (isset($test_string) && trim($test_string)) {
118  $ret['surname'] = $test_string;
119  }
120 
121  $test_string = $in_user_object->get_middle_name();
122  if (isset($test_string) && trim($test_string)) {
123  $ret['middle_name'] = $test_string;
124  }
125 
126  $test_string = $in_user_object->get_given_name();
127  if (isset($test_string) && trim($test_string)) {
128  $ret['given_name'] = $test_string;
129  }
130 
131  $test_string = $in_user_object->get_prefix();
132  if (isset($test_string) && trim($test_string)) {
133  $ret['prefix'] = $test_string;
134  }
135 
136  $test_string = $in_user_object->get_suffix();
137  if (isset($test_string) && trim($test_string)) {
138  $ret['suffix'] = $test_string;
139  }
140 
141  $test_string = $in_user_object->get_nickname();
142  if (isset($test_string) && trim($test_string)) {
143  $ret['nickname'] = $test_string;
144  }
145 
146  $tags = $in_user_object->tags();
147  if (isset($tags) && is_array($tags) && count($tags)) {
148  $test_string = $tags[7];
149  if (isset($test_string) && trim($test_string)) {
150  $ret['tag7'] = $test_string;
151  }
152 
153  $test_string = $tags[8];
154  if (isset($test_string) && trim($test_string)) {
155  $ret['tag8'] = $test_string;
156  }
157 
158  $test_string = $tags[9];
159  if (isset($test_string) && trim($test_string)) {
160  $ret['tag9'] = $test_string;
161  }
162  }
163 
164  $ret['is_manager'] = $in_user_object->is_manager();
165 
166  $ret['is_main_admin'] = $in_user_object->is_god();
167 
168  if ($in_with_login_info) {
169  $login_instance = $in_user_object->get_login_instance();
170  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login)) {
171  if ($login_instance->id() == $in_user_object->get_access_object()->get_login_id()) {
172  $ret['current_login'] = true;
173  }
174 
175  $ret['associated_login'] = $this->_get_long_description($login_instance);
176  }
177  } else {
178  $login_instance = $in_user_object->get_login_instance();
179  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login)) {
180  $ret['associated_login_id'] = $login_instance->id();
181  }
182  }
183 
184  return $ret;
185  }
186 
187  /***********************/
191  protected function _get_xsd() {
192  return $this->_process_xsd(dirname(__FILE__).'/schema.xsd');
193  }
194 
195  /***********************/
201  protected function _handle_logins( $in_andisol_instance,
202  $in_path = [],
203  $in_query = []
204  ) {
205  $ret = [];
206  $show_details = isset($in_query) && is_array($in_query) && isset($in_query['show_details']); // Flag that applies only for lists, forcing all people to be shown in detail.
207  $logged_in = isset($in_query) && is_array($in_query) && isset($in_query['logged_in']) && $in_andisol_instance->manager(); // Flag that filters for only users that are logged in.
208  $my_info = isset($in_path) && is_array($in_path) && (0 < count($in_path) && ('my_info' == $in_path[0])); // This is a directory that specifies only our own user.
209  $writeable = isset($in_query) && is_array($in_query) && isset($in_query['writeable']); // Show/list only logins this user can modify.
210 
211  if (isset($my_info) && $my_info) { // If we are just asking after our own info, then we just send that back.
212  if ($in_andisol_instance->logged_in()) {
213  $login = $in_andisol_instance->current_login();
214  if ($login instanceof CO_Security_Login) {
215  $ret['my_info'] = $this->_get_long_description($login);
216  } else {
217  header('HTTP/1.1 400 No Login Available');
218  exit();
219  }
220  } else {
221  header('HTTP/1.1 403 Forbidden');
222  exit();
223  }
224  } elseif (isset($in_path) && is_array($in_path) && (0 < count($in_path))) {
225  // See if they want the list of logins for people with logins, or particular people
226  // Now, we see if they are a list of integer IDs or strings (login string IDs).
227  $login_id_list = array_map('trim', explode(',', $in_path[0]));
228 
229  $is_numeric = array_reduce($login_id_list, function($carry, $item){ return $carry && ctype_digit($item); }, true);
230 
231  $login_id_list = $is_numeric ? array_map('intval', $login_id_list) : $login_id_list;
232  // A manager can ask for a "test" of a single login, to see if it is in use (regardless of whether or not they have view rights).
233  if (!$is_numeric && (1 == count($login_id_list)) && trim($login_id_list[0]) && isset($in_query) && is_array($in_query) && (3 == count($in_query)) && isset($in_query['test']) && $in_query['test'] && $in_andisol_instance->manager()) {
234  if ($in_andisol_instance->check_login_exists_by_login_string(trim($login_id_list[0]))) {
235  $ret = ['login_exists' => true];
236  } else {
237  $ret = ['login_exists' => false];
238  }
239  } else {
240  foreach ($login_id_list as $id) {
241  if (($is_numeric && (0 < $id)) || !$is_numeric) {
242  $login_instance = $is_numeric ? $in_andisol_instance->get_login_item($id) : $in_andisol_instance->get_login_item_by_login_string($id);
243  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login) && (!$writeable || $login_instance->user_can_write())) {
244  if (!$logged_in || ($logged_in && $login_instance->get_api_key())) { // See if they are filtering for logins.
245  if ($show_details) {
246  $ret[] = $this->_get_long_description($login_instance);
247  } else {
248  $ret[] = $this->_get_short_description($login_instance);
249  }
250  }
251  }
252  }
253  }
254  }
255  } else { // They want the list of all of them.
256  $login_id_list = $in_andisol_instance->get_all_login_users();
257  if ($in_andisol_instance->manager()) {
258  $login_id_list = $in_andisol_instance->get_all_logins();
259  if (0 < count($login_id_list)) {
260  foreach ($login_id_list as $login_instance) {
261  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login) && (!$writeable || $login_instance->user_can_write())) {
262  if (!$logged_in || ($logged_in && $login_instance->get_api_key())) { // See if they are filtering for logins.
263  if ($show_details) {
264  $ret[] = $this->_get_long_description($login_instance);
265  } else {
266  $ret[] = $this->_get_short_description($login_instance);
267  }
268  }
269  }
270  }
271  }
272  } else {
273  header('HTTP/1.1 403 Forbidden');
274  exit();
275  }
276  }
277 
278  return $ret;
279  }
280 
281  /***********************/
287  protected function _handle_edit_logins( $in_andisol_instance,
288  $in_http_method,
289  $in_path = [],
290  $in_query = [],
291  $in_show_parents = false
292  ) {
293  $ret = [];
294 
295  $logins_to_edit = [];
296 
297  $also_delete_user = false;
298 
299  if (isset($in_query) && is_array($in_query) && count($in_query) && isset($in_query['delete_user'])) {
300  $also_delete_user = true;
301  }
302 
303  $my_info = isset($in_path) && is_array($in_path) && (0 < count($in_path) && ('my_info' == $in_path[0]));
304 
305  if (isset($my_info) && $my_info) { // If we are just asking after our own info, then we just use our own login.
306  $logins_to_edit = [$in_andisol_instance->current_login()];
307  } elseif (isset($in_path) && is_array($in_path) && (0 < count($in_path))) {
308  // We see if they are a list of integer IDs or strings (login string IDs).
309  $login_id_list = array_map('trim', explode(',', $in_path[0]));
310 
311  $is_numeric = array_reduce($login_id_list, function($carry, $item){ return $carry && ctype_digit($item); }, true);
312 
313  $login_id_list = $is_numeric ? array_map('intval', $login_id_list) : $login_id_list;
314 
315  foreach ($login_id_list as $id) {
316  if (($is_numeric && (0 < $id)) || !$is_numeric) {
317  $login_instance = $is_numeric ? $in_andisol_instance->get_login_item($id) : $in_andisol_instance->get_login_item_by_login_string($id);
318  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login) && $login_instance->user_can_write()) {
319  if (('DELETE' == $in_http_method) && $also_delete_user) { // If we also want to delete the user, then we need to have write permission on the user, as well.
320  $user_instance = $login_instance->get_user_object();
321  if ($user_instance->user_can_write()) {
322  $logins_to_edit[] = $login_instance;
323  }
324  } else {
325  $logins_to_edit[] = $login_instance;
326  }
327  }
328  }
329  }
330  } elseif ($in_andisol_instance->manager()) { // Must have a COBRA instance, and be a manager
331  $login_id_list = $in_andisol_instance->get_all_logins();
332  if (0 < count($login_id_list)) {
333  foreach ($login_id_list as $login_instance) {
334  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login) && $login_instance->user_can_write()) {
335  if (('DELETE' == $in_http_method) && $also_delete_user) { // If we also want to delete the user, then we need to have write permission on the user, as well.
336  $user_instance = $login_instance->get_user_object();
337  if ($user_instance->user_can_write()) {
338  $logins_to_edit[] = $login_instance;
339  }
340  } else {
341  $logins_to_edit[] = $login_instance;
342  }
343  }
344  }
345  }
346  }
347 
348  if (('POST' == $in_http_method) && $in_andisol_instance->manager()) {
349  $ret = $this->_handle_edit_logins_post($in_andisol_instance, $in_path, $in_query);
350  } elseif (isset($logins_to_edit) && is_array($logins_to_edit) && count($logins_to_edit)) {
351  if (('DELETE' == $in_http_method) && $in_andisol_instance->manager()) {
352  if (!$also_delete_user) {
353  $in_show_parents = false; // Doesn't count, unless we are deleting a user. Logins can't have parents.
354  }
355  $ret = $this->_handle_edit_logins_delete($in_andisol_instance, $logins_to_edit, $in_query, $also_delete_user, $in_show_parents);
356  } elseif ('PUT' == $in_http_method) { // Of course, there's always an exception. People can edit their own users.
357  $ret = $this->_handle_edit_logins_put($in_andisol_instance, $logins_to_edit, $in_query);
358  }
359  }
360 
361  return $ret;
362  }
363 
364  /***********************/
370  protected function _handle_edit_logins_post( $in_andisol_instance,
371  $in_path = [],
372  $in_query = []
373  ) {
374  $ret = [];
375 
376  $lang = NULL;
377  $name = NULL;
378  $read_token = NULL;
379 
380  if ($in_andisol_instance->manager()) { // Must be a manager
381  $write_token = NULL;
382  $is_manager = isset($in_query) && is_array($in_query) && isset($in_query['is_manager']);
383  if (isset($in_query['is_manager'])) {
384  unset($in_query['is_manager']);
385  }
386 
387  $login_id = NULL;
388  $login_string = (isset($in_query['login_string']) && trim($in_query['login_string'])) ? trim($in_query['login_string']) : NULL;
389 
390  // The first thing we do, is see if a login ID was supplied on the path.
391  if (isset($in_path) && is_array($in_path) && (0 < count($in_path)) && trim($in_path[0])) {
392  $login_id = trim($in_path[0]);
393  } elseif (isset($in_query) && isset($in_query['login_id']) && trim($in_query['login_id'])) { // How about as a query argument?
394  $login_id = trim($in_query['login_id']);
395  }
396 
397  if ($login_id) { // 'login_string' is deprecated. 'login_id' trumps it.
398  $login_string = $login_id;
399  }
400 
401  if ($login_string) { // Minimum is a login string.
402  $params = $this->_build_login_mod_list($in_andisol_instance, $in_query);
403 
404  if (isset($params['lang']) && trim($params['lang'])) {
405  $lang = trim($params['lang']);
406  }
407 
408  if (isset($params['name']) && trim($params['name'])) {
409  $name = trim($params['name']);
410  }
411 
412  if (isset($params['read_token']) && intval($params['read_token'])) {
413  $read_token = intval($params['read_token']);
414  }
415 
416  if (isset($params['write_token']) && intval($params['write_token'])) {
417  $write_token = intval($params['write_token']);
418  }
419 
420  $result = true;
421 
422  if ($is_manager) {
423  $new_login = NULL;
424 
425  $password = isset($params['password']) ? $params['password'] : NULL;
426 
427  if (!$password || (strlen($password) < CO_Config::$min_pw_len)) {
428  $password = substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), 0, CO_Config::$min_pw_len + 2);
429  }
430 
431  $number_of_personal_tokens = (isset($in_query['number_of_personal_tokens']) && trim($in_query['number_of_personal_tokens'])) ? intval(trim($in_query['number_of_personal_tokens'])) : 0;
432 
433  if ($is_manager) {
434  $new_login = $in_andisol_instance->create_new_manager_login($login_string, $password, $number_of_personal_tokens);
435  } else {
436  $new_login = $in_andisol_instance->create_new_standard_login($login_string, $password, $number_of_personal_tokens);
437  }
438 
439  if ($new_login instanceof CO_Security_Login) {
440  if ($lang) {
441  $result = $new_login->set_lang($lang);
442  }
443 
444  $tokens = isset($params['tokens']) ? $params['tokens'] : NULL;
445  $id = $new_login->id();
446 
447  // If we did not have a name sent in, then we simply use the login ID.
448  if ($result && $name) {
449  $result = $new_login->set_name($name);
450  } elseif ($result) {
451  $result = $new_login->set_name($login_string);
452  }
453 
454  if (isset($tokens) && is_array($tokens) && count($tokens)) {
455  $new_login->set_ids($tokens);
456  }
457 
458  if (!$result) {
459  header('HTTP/1.1 400 Error Creating Login');
460  exit();
461  }
462  // See if we explicitly set security tokens.
463  if (isset($read_token)) {
464  $new_login->set_read_security_id($read_token);
465  }
466 
467  if (isset($write_token)) {
468  $new_login->set_write_security_id($write_token);
469  }
470 
471  $ret = Array('new_login' => $this->_get_long_description($new_login));
472  $ret['new_login']['password'] = $password;
473  }
474  } else {
475  header('HTTP/1.1 403 Forbidden');
476  exit();
477  }
478  } else {
479  header('HTTP/1.1 400 Login String Required');
480  exit();
481  }
482  } else {
483  header('HTTP/1.1 403 Forbidden');
484  exit();
485  }
486 
487  return $ret;
488  }
489 
490  /***********************/
496  protected function _handle_edit_logins_delete( $in_andisol_instance,
497  $in_logins_to_edit,
498  $in_query = [],
499  $in_also_delete_user = false,
500  $in_show_parents = false
501  ) {
502  $ret = [];
503 
504  if ($in_andisol_instance->manager()) { // Only managers can delete.
505  $ret = Array ('deleted_logins' => []);
506 
507  if ($in_also_delete_user) {
508  $ret['deleted_users'] = [];
509  }
510 
511  foreach ($in_logins_to_edit as $login_object) {
512  if ($login_object->id() != CO_Config::god_mode_id()) { // Can't delete God.
513  if ($in_also_delete_user) { // Do we want to delete any associated user object?
514  $user_object = $login_object->get_user_object();
515  if (isset($user_object) && $user_object->user_can_write()) {
516  $desc = $this->_get_long_user_description($user_object);
517  if (!$user_object->delete_from_db()) {
518  header('HTTP/1.1 400 Unable to Delete User');
519  exit();
520  } else {
521  $ret['deleted_users'][] = $desc;
522  }
523  }
524  }
525 
526  $desc = $this->_get_long_description($login_object);
527  if (!$login_object->delete_from_db()) {
528  header('HTTP/1.1 400 Unable to Delete Login');
529  exit();
530  } else {
531  $ret['deleted_logins'][] = $desc;
532  }
533  } else {
534  header('HTTP/1.1 400 Cannot Delete Main Admin Login');
535  exit();
536  }
537  }
538  } else {
539  header('HTTP/1.1 403 Forbidden');
540  exit();
541  }
542 
543  return $ret;
544  }
545 
546  /***********************/
552  protected function _handle_edit_logins_put( $in_andisol_instance,
553  $in_logins_to_edit,
554  $in_query = []
555  ) {
556  $ret = [];
557  $params = $this->_build_login_mod_list($in_andisol_instance, $in_query);
558 
559  $lang = NULL;
560  $name = NULL;
561  $password = NULL;
562  $login_string = NULL;
563  $read_token = NULL;
564  $write_token = NULL;
565  $tokens = NULL;
566  $personal_tokens = NULL;
567  $convert_to_manager = NULL;
568  $convert_to_login = NULL;
569 
570  // If the instances are currently logins, they will be converted to managers.
571  if (isset($in_query['convert_to_manager'])) {
572  $convert_to_manager = true;
573  }
574 
575  // If the instances are currently managers, they will be converted to logins.
576  if (!$convert_to_manager && isset($in_query['convert_to_login'])) {
577  $convert_to_login = true;
578  }
579 
580  if (isset($params['lang']) && trim($params['lang'])) {
581  $lang = trim($params['lang']);
582  }
583 
584  if (isset($params['name']) && trim($params['name'])) {
585  $name = trim($params['name']);
586  }
587 
588  if (isset($params['password']) && trim($params['password'])) {
589  $password = trim($params['password']);
590  }
591 
592  if (isset($params['login_string']) && trim($params['login_string'])) {
593  $login_string = trim($params['login_string']);
594  }
595 
596  if (isset($params['read_token']) && $params['read_token']) {
597  $read_token = intval($params['read_token']);
598  }
599 
600  if (isset($params['write_token']) && $params['write_token']) {
601  $write_token = intval($params['write_token']);
602  }
603 
604  if (isset($params['tokens'])) {
605  $tokens = array_filter(array_map('intval', $params['tokens']), function($i) { return intval($i) > 0; } );
606  sort($tokens);
607  }
608 
609  if (isset($params['personal_tokens'])) {
610  $personal_tokens = array_filter(array_map('intval', $params['personal_tokens']), function($i) { return intval($i) > 0; } );
611  sort($personal_tokens);
612  }
613 
614  foreach ($in_logins_to_edit as $login_instance) {
615  $result = true;
616  $login_report = Array('before' => $this->_get_long_description($login_instance));
617  $login_changed = false;
618  $changed_password = NULL;
619  $can_edit = $login_instance->user_can_edit_ids();
620 
621  // We ignore attempts to set tokens that we don't own.
622  if (isset($tokens) && $can_edit) {
623  $new_tokens = [];
624 
625  foreach ($tokens as $token) {
626  $token = intval($token);
627  if ($in_andisol_instance->i_have_this_token(abs($token))) {
628  $new_tokens[] = $token;
629  }
630  }
631 
632  $result = $login_instance->set_ids($new_tokens);
633 
634  if ($result) {
635  $login_changed = true;
636  }
637  }
638 
639  // Only God can set personal tokens.
640  if (isset($personal_tokens) && $in_andisol_instance->god()) {
641  $result = $login_instance->set_personal_ids($personal_tokens);
642  if ($result || !$personal_tokens || !count($personal_tokens)) {
643  $login_changed = true;
644  }
645  }
646 
647  // This is a rare and special occasion. The login change may fail, as it's possible to assign a login that already exists.
648  // Additionally, this will only apply to the FIRST login encountered, as, by definition, login strings are unique.
649  if ($login_string) {
650  if ($in_andisol_instance->god()) { // Only God can change login strings.
651  $original_login = $login_instance->login_id;
652  $login_instance->login_id = $login_string;
653 
654  $result = $login_instance->update_db(); // This will fail if the new login is not valid. It must be unique, globally.
655 
656  if ($result) {
657  $result = $login_instance->clear_api_key(); // Doing this invalidates any current logins.
658  $login_changed = true;
659  $login_string = NULL;
660  } else {
661  header('HTTP/1.1 400 Cannot Set New Login');
662  exit();
663  }
664  }
665  }
666 
667  if ($lang) {
668  $result = $login_instance->set_lang($lang);
669  if ($result) {
670  $login_changed = true;
671  }
672  }
673 
674  if ($result && $name) {
675  $result = $login_instance->set_name($name);
676  if ($result) {
677  $login_changed = true;
678  }
679  }
680 
681  if (($result && $password) && ($in_andisol_instance->manager() || ($login_instance == $in_andisol_instance->get_login_item()))) {
682  $result = $login_instance->set_password_from_cleartext($password);
683  if ($result) {
684  $result = $login_instance->clear_api_key(); // Doing this invalidates any current logins.
685  if ($result) {
686  $changed_password = $password;
687  $login_changed = true;
688  }
689  }
690  }
691 
692  if ($result && $read_token) {
693  $result = $login_instance->set_read_security_id($read_token);
694  if ($result) {
695  $login_changed = true;
696  }
697  }
698 
699  if ($result && $write_token) {
700  $result = $login_instance->set_write_security_id($write_token);
701  if ($result) {
702  $login_changed = true;
703  }
704  }
705 
706  if ($result && $convert_to_manager && !$login_instance->is_manager()) {
707  $result = $in_andisol_instance->convert_login($login_instance->login_id, true);
708  if ($result) {
709  $login_changed = true;
710  }
711  }
712 
713  if ($result && $convert_to_login && $login_instance->is_manager()) {
714  $result = $in_andisol_instance->convert_login($login_instance->login_id, false);
715  if ($result) {
716  $login_changed = true;
717  }
718  }
719 
720  if (!$login_changed) {
721  header('HTTP/1.1 400 Error Modifying Login');
722  exit();
723  }
724 
725  if ($login_changed) {
726  $login_report['after'] = $this->_get_long_description($login_instance);
727  if ($changed_password) {
728  $login_report['after']['password'] = $changed_password;
729  }
730 
731  $ret['changed_logins'][] = $login_report;
732  }
733  }
734 
735  return $ret;
736  }
737 
738  /***********************/
744  protected function _handle_personal_ids( $in_andisol_instance,
745  $in_path = [],
746  $in_query = []
747  ) {
748  $ret = [];
749  $my_info = isset($in_path) && is_array($in_path) && (0 < count($in_path) && ('my_info' == $in_path[0]) && $in_andisol_instance->logged_in()); // This is a directory that specifies only our own user.
750  if ($my_info) {
751  $tokens = $in_andisol_instance->get_personal_security_ids();
752  if (isset($tokens) && is_array($tokens) && count($tokens)) {
753  $ret['my_info']['tokens'] = $tokens;
754  }
755 
756  $user_list = $in_andisol_instance->get_logins_that_have_any_of_my_ids();
757  $ret_temp = [];
758  if (is_array($user_list) && count($user_list)) {
759  foreach ($user_list as $key => $value) {
760  $ret_temp[] = ["id" => $key, "tokens" => $value];
761  }
762  }
763  if (count($ret_temp)) {
764  $ret['my_info']['personal_token_users'] = $ret_temp;
765  }
766  } elseif ($in_andisol_instance->god()) {
767  $all_logins = $in_andisol_instance->get_all_logins();
768 
769  if (isset($all_logins) && is_array($all_logins) && count($all_logins)) {
770  $ret_temp = [];
771  foreach ($all_logins as $login) {
772  $tokens = $login->personal_ids();
773  if (isset($tokens) && is_array($tokens) && count($tokens)) {
774  $ret_temp[] = ["id" => $login->id(), "tokens" => $tokens];
775  }
776  }
777  $ret = ["personal_token_users" => $ret_temp];
778  }
779  } else {
780  header('HTTP/1.1 403 Not Permitted'); // Ah-Ah-Aaaahh! You didn't say the magic word!
781  exit();
782  }
783 
784  return $ret;
785  }
786 
787  /***********************/
793  protected function _handle_edit_personal_ids( $in_andisol_instance,
794  $in_http_method,
795  $in_path = [],
796  $in_query = []
797  ) {
798  $ret = [];
799 
800  if ('PUT' == $in_http_method) {
801  if (isset($in_path) && is_array($in_path) && (0 < count($in_path)) && trim($in_path[0])) {
802  $token_list = array_map('intval', explode(",",trim($in_path[0])));
803  }
804  if (isset($in_query) && is_array($token_list) && count($token_list)) {
805  // Assign tokens directly to a user. This can only be done by the God Admin, and it completely replaces all the personal tokens of that user.
806  if (is_array($in_query) && isset($in_query['set_user_tokens']) && $in_query['set_user_tokens'] && $in_andisol_instance->god()) {
807  $user_id = intval($in_query['set_user_tokens']);
808  $tokens = $in_andisol_instance->set_personal_ids($user_id, $token_list);
809 
810  if (count($tokens)) {
811  $ret['set_user_tokens'] = ['id' => $user_id, 'tokens' => $tokens];
812  }
813  // Assign tokens from our pool, to another user.
814  } elseif (is_array($in_query) && isset($in_query['assign_tokens_to_user'])) {
815  $results = [];
816  $user_ids = array_map('intval', explode(",", $in_query['assign_tokens_to_user']));
817 
818  foreach($user_ids as $user_id) {
819  $ret_temp2 = [];
820  foreach ($token_list as $token) {
821  if ($in_andisol_instance->add_personal_token_from_current_login($user_id, $token)) {
822  $ret_temp2[] = $token;
823  }
824  }
825  if (count($ret_temp2)) {
826  $ret_temp[] = ["id" => $user_id, "tokens" => $ret_temp2];
827  }
828  }
829 
830  $ret['assign_tokens_to_user'] = $ret_temp;
831  // Remove one or more of our tokens from another user.
832  } elseif (is_array($in_query) && isset($in_query['remove_tokens_from_user']) && isset($in_query['remove_tokens_from_user'])) {
833  $ret_temp = [];
834  $user_id = intval($in_query['remove_tokens_from_user']);
835 
836  foreach ($token_list as $token) {
837  if ($in_andisol_instance->remove_personal_token_from_this_login($user_id, $token)) {
838  $ret_temp[] = $token;
839  }
840  }
841 
842  $ret['remove_tokens_from_user'] = ['id' => $user_id, 'tokens' => $ret_temp];
843  // Remove one or more of our tokens, from all other users that have the token.
844  } elseif (is_array($in_query) && isset($in_query['remove_all_these_tokens_from_all_users']) && isset($in_query['remove_all_these_tokens_from_all_users'])) {
845  $user_list = $in_andisol_instance->get_logins_that_have_any_of_my_ids();
846  $ret_temp = [];
847  foreach ($user_list as $user_id => $token_list) {
848  $ret_temp2 = [];
849  foreach ($token_list as $token) {
850  if ($in_andisol_instance->remove_personal_token_from_this_login($user_id, $token)) {
851  $ret_temp2[] = $token;
852  }
853  }
854  if (count($ret_temp2)) {
855  $ret_temp[] = ["id" => $user_id, "tokens" => $ret_temp2];
856  }
857  }
858 
859  $ret = ["remove_all_these_tokens_from_all_users" => $ret_temp];
860  } else {
861  header('HTTP/1.1 400 Incorrect Command Structure');
862  exit();
863  }
864  } else {
865  header('HTTP/1.1 400 No Personal IDs');
866  exit();
867  }
868  } else {
869  header('HTTP/1.1 400 Incorrect HTTP Request Method');
870  exit();
871  }
872 
873  return $ret;
874  }
875 
876  /***********************/
882  protected function _build_login_mod_list( $in_andisol_instance,
883  $in_query = NULL
884  ) {
885  $ret = []; // We will build up an associative array of changes we want to make.
886 
887  if (isset($in_query) && is_array($in_query) && count($in_query)) {
888  // These are the regular security tokens.
889  if (isset($in_query['tokens'])) {
890  $ret['tokens'] = array_map('intval', explode(',', $in_query['tokens']));
891  sort($ret['tokens']);
892  if (1 == $ret['tokens'][0]) { // Just in case the knucklehead sent the "all logged in" token.
893  array_shift($ret['tokens']);
894  }
895  }
896 
897  // Personal tokens can only be modified by God
898  if (isset($in_query['personal_tokens']) && $in_andisol_instance->god()) {
899  $ret['personal_tokens'] = array_map('intval', explode(',', $in_query['personal_tokens']));
900  sort($ret['personal_tokens']);
901  }
902 
903  // Next, we see if we want to change the password.
904  if (isset($in_query['password']) && (strlen(trim($in_query['password'])) >= CO_Config::$min_pw_len)) {
905  $ret['password'] = trim($in_query['password']);
906  }
907 
908  // Next, we see if we want to change/set the login object asociated with this. You can remove an associated login object by passing in NULL or 0, here.
909  if (isset($in_query['login_string']) && $in_andisol_instance->god()) { // Only God can change login strings (unless we are creating a new user).
910  $ret['login_string'] = trim($in_query['login_string']);
911  }
912 
913  // Next, we see if we want to change the read security.
914  if (isset($in_query['read_token'])) {
915  $ret['read_token'] = intval($in_query['read_token']);
916  }
917 
918  // Next, we see if we want to change the write security.
919  if (isset($in_query['write_token'])) {
920  $ret['write_token'] = intval($in_query['write_token']);
921  }
922 
923  // Next, we see if we want to change the name.
924  if (isset($in_query['name'])) {
925  $ret['name'] = trim(strval($in_query['name']));
926  }
927 
928  // Next, look for the language.
929  if (isset($in_query['lang'])) {
930  $ret['lang'] = trim(strval($in_query['lang']));
931  }
932  }
933 
934  return $ret;
935  }
936 
937  /***********************/
943  protected function _handle_edit_people( $in_andisol_instance,
944  $in_http_method,
945  $in_path = [],
946  $in_query = [],
947  $in_show_parents = false
948  ) {
949  $ret = NULL;
950 
951  $login_user = isset($in_query) && is_array($in_query) && isset($in_query['login_user']); // Flag saying they are only looking for login people.
952 
953  // You need to be a manager for most of these. If you are not a manager, then you simply get an "incorrect method" response, as opposed to a "forbidden" response.
954  if (('POST' == $in_http_method) && $in_andisol_instance->manager()) {
955  $ret = $this->_handle_edit_people_post($in_andisol_instance, $login_user, $in_path, $in_query);
956  } elseif (('DELETE' == $in_http_method) && $in_andisol_instance->manager()) {
957  $ret = $this->_handle_edit_people_delete($in_andisol_instance, $login_user, $in_path, $in_query, $in_show_parents);
958  } elseif ('PUT' == $in_http_method) { // Of course, there's always an exception. People can edit their own users.
959  $ret = $this->_handle_edit_people_put($in_andisol_instance, $login_user, $in_path, $in_query);
960  } else {
961  header('HTTP/1.1 400 Incorrect HTTP Request Method'); // Ah-Ah-Aaaahh! You didn't say the magic word!
962  exit();
963  }
964 
965  return $ret;
966  }
967 
968  /***********************/
976  protected function _handle_edit_people_put( $in_andisol_instance,
977  $in_login_user,
978  $in_path = [],
979  $in_query = []
980  ) {
981  $ret = NULL;
982 
983  $user_object_list = [];
984 
985  $my_info = isset($in_path) && is_array($in_path) && (0 < count($in_path) && ('my_info' == $in_path[0]));
986 
987  if (isset($my_info) && $my_info) { // If we are just asking after our own info, then we just use our own user.
988  $user_object_list[] = $in_andisol_instance->current_user();
989  } elseif (isset($in_path) && is_array($in_path) && (1 < count($in_path) && isset($in_path[0]) && ('login_ids' == $in_path[0]))) { // See if they are looking for people associated with string login IDs.
990  // Now, we see if they are a list of integer IDs or strings (login string IDs).
991  $login_id_list = array_map('trim', explode(',', $in_path[1]));
992 
993  $is_numeric = array_reduce($login_id_list, function($carry, $item){ return $carry && ctype_digit($item); }, true);
994 
995  $login_id_list = $is_numeric ? array_map('intval', $login_id_list) : $login_id_list;
996  $login_id_list = array_unique($login_id_list);
997 
998  foreach ($login_id_list as $login_id) {
999  $login_instance = $is_numeric ? $in_andisol_instance->get_login_item($login_id) : $in_andisol_instance->get_login_item_by_login_string($login_id);
1000 
1001  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login)) {
1002  $id_string = $login_instance->login_id;
1003  $user = $in_andisol_instance->get_user_from_login_string($id_string);
1004  if ($user->user_can_write() && $user->has_login()) {
1005  $user_object_list[] = $user;
1006  }
1007  }
1008  }
1009  } elseif (isset($in_path) && is_array($in_path) && (0 < count($in_path))) { // See if they are looking for a list of individual discrete integer IDs.
1010  $user_nums = strtolower($in_path[0]);
1011 
1012  $single_user_id = (ctype_digit($user_nums) && (1 < intval($user_nums))) ? intval($user_nums) : NULL; // This will be set if we are looking for only one single user.
1013  // The first thing that we'll do, is look for a list of user IDs. If that is the case, we split them into an array of int.
1014  $user_list = explode(',', $user_nums);
1015 
1016  // If we do, indeed, have a list, we will force them to be ints, and cycle through them.
1017  if ($single_user_id || (1 < count($user_list))) {
1018  $user_list = array_unique($single_user_id ? [$single_user_id] : array_map('intval', $user_list));
1019 
1020  foreach ($user_list as $id) {
1021  if (0 < $id) {
1022  $user = $in_andisol_instance->get_single_data_record_by_id($id);
1023  if (isset($user) && ($user instanceof CO_User_Collection)) {
1024  if (!$in_login_user || ($in_login_user && $user->has_login()) && $user->user_can_write()) {
1025  $user_object_list[] = $user;
1026  }
1027  }
1028  }
1029  }
1030  }
1031  } else {
1032  $userlist = $in_andisol_instance->get_all_users();
1033  if (0 < count($userlist)) {
1034  foreach ($userlist as $user) {
1035  if (isset($user) && ($user instanceof CO_User_Collection)) {
1036  if (!$in_login_user || ($in_login_user && $user->has_login()) && $user->user_can_write()) {
1037  $user_object_list[] = $user;
1038  }
1039  }
1040  }
1041  }
1042  }
1043 
1044  // At this point, we have a list of writable user objects.
1045  // Now, if we are not a manager, then the only object we have the right to alter is our own.
1046  if (!$in_andisol_instance->manager()) {
1047  $temp = NULL;
1048 
1049  $current_user = $in_andisol_instance->current_user();
1050 
1051  foreach ($user_object_list as $user) {
1052  if ($user == $current_user) {
1053  $temp = $user;
1054  break;
1055  }
1056  }
1057 
1058  $user_object_list = [];
1059 
1060  if (isset($temp)) {
1061  $user_object_list = [$temp];
1062  }
1063  }
1064 
1065 
1066  // At this point, we have a fully-vetted list of users for modification, or none. If none, we react badly.
1067  if (0 == count($user_object_list)) {
1068  header('HTTP/1.1 403 No Editable Records'); // I don't think so. Homey don't play that game.
1069  exit();
1070  } else {
1071  $mod_list = $this->_build_user_mod_list($in_andisol_instance, 'PUT', $in_query);
1072  $ret = [];
1073 
1074  foreach ($user_object_list as $user) {
1075  $changed_password = NULL;
1076  $user_changed = false;
1077  if ($user->user_can_write()) { // We have to be allowed to write to this user.
1078  $user_report = Array('before' => $this->_get_long_user_description($user, $in_login_user));
1079 
1080  $user->set_batch_mode();
1081  $result = false;
1082 
1083  foreach ($mod_list as $key => $value) {
1084  switch ($key) {
1085  case 'child_ids':
1086  if ('DELETE-ALL' == $value) { // This means remove everything.
1087  $result = $user->deleteAllChildren();
1088  $user_changed = true;
1089  } else {
1090  $add = $value['add'];
1091  $remove = $value['remove'];
1092  $result = true;
1093 
1094  foreach ($remove as $id) {
1095  if ($id != $user->id()) {
1096  $child = $in_andisol_instance->get_single_data_record_by_id($id);
1097  if (isset($child)) {
1098  $result = $user->deleteThisElement($child);
1099  $user_changed = true;
1100  }
1101 
1102  if (!$result) {
1103  break;
1104  }
1105  }
1106  }
1107 
1108  if ($result) {
1109  foreach ($add as $id) {
1110  if ($id != $user->id()) {
1111  $child = $in_andisol_instance->get_single_data_record_by_id($id);
1112  if (isset($child)) {
1113  $result = $user->appendElement($child);
1114  $user_changed = true;
1115 
1116  if (!$result) {
1117  break;
1118  }
1119  }
1120  }
1121  }
1122  }
1123  }
1124  break;
1125 
1126  case 'password':
1127  if ($in_login_user) {
1128  $login_instance = $user->get_login_instance();
1129 
1130  // Only the user, themselves, or a manager with edit rights on the login, can change the password.
1131  if ($login_instance) {
1132  if (($in_andisol_instance->manager() || ($login_instance == $in_andisol_instance->current_login()) && $login_instance->user_can_write())) {
1133  $result = $login_instance->set_password_from_cleartext($value);
1134  if ($result) {
1135  $result = $login_instance->clear_api_key(); // Doing this invalidates any current logins.
1136  if ($result) {
1137  $changed_password = $value;
1138  $user_changed = true;
1139  }
1140  }
1141  } else {
1142  header('HTTP/1.1 403 Forbidden');
1143  exit();
1144  }
1145  } else {
1146  header('HTTP/1.1 400 No Login Item');
1147  exit();
1148  }
1149  }
1150 
1151  break;
1152 
1153  case 'lang':
1154  $result = $user->set_lang($value);
1155 
1156  if ($result && $in_login_user) {
1157  $login_instance = $user->get_login_instance();
1158 
1159  if ($login_instance && $login_instance->user_can_write()) {
1160  $result = $login_instance->set_lang($value);
1161  $user_changed = true;
1162  }
1163  }
1164 
1165  break;
1166 
1167  case 'write_token':
1168  $result = $user->set_write_security_id($value);
1169  $user_changed = true;
1170  break;
1171 
1172  case 'read_token':
1173  $result = $user->set_read_security_id($value);
1174  $user_changed = true;
1175  break;
1176 
1177  case 'longitude':
1178  $result = $user->set_longitude($value);
1179  $user_changed = true;
1180  break;
1181 
1182  case 'latitude':
1183  $result = $user->set_latitude($value);
1184  $user_changed = true;
1185  break;
1186 
1187  case 'fuzz_factor':
1188  $result = $user->set_fuzz_factor($value);
1189  $user_changed = true;
1190  break;
1191 
1192  case 'can_see_through_the_fuzz':
1193  $result = $user->set_can_see_through_the_fuzz($value);
1194  $user_changed = true;
1195  break;
1196 
1197  case 'tokens':
1198  if ($in_login_user) { // Can only do this, if the caller explicitly requested a login user.
1199  $login_instance = $user->get_login_instance();
1200 
1201  if ($login_instance) {
1202  $result = $login_instance->set_ids($value);
1203  $user_changed = true;
1204  }
1205  } else {
1206  header('HTTP/1.1 400 Improper Data Provided');
1207  exit();
1208  }
1209  break;
1210 
1211  case 'personal_tokens':
1212  if ($in_login_user && $in_andisol_instance->god()) { // Can only do this, if the caller explicitly requested a login user, and we are a God.
1213  $login_instance = $user->get_login_instance();
1214 
1215  if ($login_instance) {
1216  $result = $login_instance->set_personal_ids($value);
1217  $user_changed = true;
1218  }
1219  } else {
1220  header('HTTP/1.1 400 Improper Data Provided');
1221  exit();
1222  }
1223  break;
1224 
1225  case 'payload':
1226  $result = $user->set_payload($value);
1227  $user_changed = true;
1228  break;
1229 
1230  case 'remove_payload':
1231  $result = $user->set_payload(NULL);
1232  $user_changed = true;
1233  break;
1234 
1235  case 'name':
1236  $result = $user->set_name($value);
1237  $user_changed = true;
1238  break;
1239 
1240  case 'surname':
1241  $result = $user->set_surname($value);
1242  $user_changed = true;
1243  break;
1244 
1245  case 'middle_name':
1246  $result = $user->set_middle_name($value);
1247  $user_changed = true;
1248  break;
1249 
1250  case 'given_name':
1251  $result = $user->set_given_name($value);
1252  $user_changed = true;
1253  break;
1254 
1255  case 'prefix':
1256  $result = $user->set_prefix($value);
1257  $user_changed = true;
1258  break;
1259 
1260  case 'suffix':
1261  $result = $user->set_suffix($value);
1262  $user_changed = true;
1263  break;
1264 
1265  case 'nickname':
1266  $result = $user->set_nickname($value);
1267  $user_changed = true;
1268  break;
1269 
1270  case 'tag7':
1271  $result = $user->set_tag(7, $value);
1272  $user_changed = true;
1273  break;
1274 
1275  case 'tag8':
1276  $result = $user->set_tag(8, $value);
1277  $user_changed = true;
1278  break;
1279 
1280  case 'tag9':
1281  $result = $user->set_tag(9, $value);
1282  $user_changed = true;
1283  break;
1284 
1285  // Only God can associate a new login at this point.
1286  case 'login_id':
1287  if ($in_andisol_instance->god()) {
1288  $result = $user->set_login(intval($value));
1289  $user_changed = true;
1290  }
1291  break;
1292  }
1293  }
1294 
1295  $result = $user->clear_batch_mode();
1296 
1297  if (!$result) {
1298  break;
1299  }
1300 
1301  if ($user_changed) {
1302  $user_report['after'] = $this->_get_long_user_description($user, $in_login_user);
1303  if ($changed_password) {
1304  $user_report['after']['associated_login']['password'] = $changed_password;
1305  }
1306 
1307  $ret['changed_users'][] = $user_report;
1308  }
1309  }
1310  }
1311  }
1312 
1313  return $ret;
1314  }
1315 
1316  /***********************/
1322  protected function _handle_edit_people_delete ( $in_andisol_instance,
1323  $in_login_user,
1324  $in_path = [],
1325  $in_query = [],
1326  $in_show_parents = false
1327  ) {
1328  $ret = NULL;
1329 
1330  // We build up a userlist.
1331  $user_object_list = [];
1332 
1333  if (isset($my_info) && $my_info) { // If we are just asking after our own info, then we just use our own user.
1334  $user_object_list = [$in_andisol_instance->current_user()];
1335  } elseif (isset($in_path) && is_array($in_path) && (1 < count($in_path) && ('login_ids' == $in_path[0]))) { // See if they are looking for people associated with string login IDs.
1336  // Now, we see if they are a list of integer IDs or strings (login string IDs).
1337  $login_id_list = array_map('trim', explode(',', $in_path[1]));
1338 
1339  $is_numeric = array_reduce($login_id_list, function($carry, $item){ return $carry && ctype_digit($item); }, true);
1340 
1341  $login_id_list = $is_numeric ? array_map('intval', $login_id_list) : $login_id_list;
1342 
1343  foreach ($login_id_list as $login_id) {
1344  $login_instance = $is_numeric ? $in_andisol_instance->get_login_item($login_id) : $in_andisol_instance->get_login_item_by_login_string($login_id);
1345 
1346  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login)) {
1347  $id_string = $login_instance->login_id;
1348  $user = $in_andisol_instance->get_user_from_login_string($id_string);
1349  if ($user->user_can_write() && $user->has_login()) {
1350  $user_object_list[] = $user;
1351  }
1352  }
1353  }
1354  } elseif (isset($in_path) && is_array($in_path) && (0 < count($in_path))) { // See if they are looking for a list of individual discrete integer IDs.
1355  $user_nums = strtolower($in_path[0]);
1356 
1357  $single_user_id = (ctype_digit($user_nums) && (1 < intval($user_nums))) ? intval($user_nums) : NULL; // This will be set if we are looking for only one single user.
1358  // The first thing that we'll do, is look for a list of user IDs. If that is the case, we split them into an array of int.
1359  $user_list = explode(',', $user_nums);
1360 
1361  // If we do, indeed, have a list, we will force them to be ints, and cycle through them.
1362  if ($single_user_id || (1 < count($user_list))) {
1363  $user_list = ($single_user_id ? [$single_user_id] : array_map('intval', $user_list));
1364 
1365  foreach ($user_list as $id) {
1366  if (0 < $id) {
1367  $user = $in_andisol_instance->get_single_data_record_by_id($id);
1368  if (isset($user) && ($user instanceof CO_User_Collection)) {
1369  if (!$in_login_user || ($in_login_user && $user->has_login()) && $user->user_can_write()) {
1370  $user_object_list[] = $user;
1371  }
1372  }
1373  }
1374  }
1375  }
1376  } else {
1377  $userlist = $in_andisol_instance->get_all_users();
1378  if (0 < count($userlist)) {
1379  foreach ($userlist as $user) {
1380  if (isset($user) && ($user instanceof CO_User_Collection)) {
1381  if (!$in_login_user || ($in_login_user && $user->has_login()) && $user->user_can_write()) {
1382  $user_object_list[] = $user;
1383  }
1384  }
1385  }
1386  }
1387  }
1388 
1389  // At this point, we have a list of writable user objects.
1390  // Now, if we are not a manager, then the only object we have the right to alter is our own.
1391  if (!$in_andisol_instance->manager()) {
1392  $temp = NULL;
1393  foreach ($user_object_list as $user) {
1394  if ($user == $in_andisol_instance->current_user()) {
1395  $temp = $user;
1396  break;
1397  }
1398  }
1399 
1400  $user_object_list = [];
1401 
1402  if (isset($temp)) {
1403  $user_object_list = [$temp];
1404  }
1405  }
1406 
1407  // At this point, we have a fully-vetted list of users for modification, or none. If none, we react badly.
1408  if (0 == count($user_object_list)) {
1409  header('HTTP/1.1 403 No Editable Records'); // I don't think so. Homey don't play that game.
1410  exit();
1411  } else { // DELETE is fairly straightforward
1412  // We also can't delete ourselves, so we will remove any items that are us.
1413  $temp = [];
1414  foreach ($user_object_list as $user) {
1415  if ($user != $in_andisol_instance->current_user()) {
1416  $temp[] = $user;
1417  }
1418  }
1419 
1420  $user_object_list = $temp;
1421 
1422  // We now have a list of items to delete. However, we also need to see if we have full rights to logins, if logins were also indicated.
1423  if ($in_login_user) { // We can only delete user/login pairs for which we have write permissions on both.
1424  $temp = [];
1425  foreach ($user_object_list as $user) {
1426  $login_item = $user->get_login_instance();
1427  if ($login_item->user_can_write()) {
1428  $temp[] = $user;
1429  }
1430  }
1431 
1432  $user_object_list = $temp;
1433  }
1434 
1435  // See what we have left. If nothing, throw a hissy fit.
1436  if (0 == count($user_object_list)) {
1437  header('HTTP/1.1 403 No Editable Records'); // I don't think so. Homey don't play that game.
1438  exit();
1439  }
1440 
1441  $ret = Array ('deleted_users' => [], 'deleted_logins' => []);
1442 
1443  // Now, we have a full list of users that we have permission to delete.
1444  foreach ($user_object_list as $user) {
1445  $user_dump = $this->_get_long_user_description($user, $in_login_user, $in_show_parents);
1446  $login_dump = NULL;
1447 
1448  $ok = true;
1449 
1450  if ($in_login_user) {
1451  $login_item = $user->get_login_instance();
1452  $login_dump = $this->_get_long_description($login_item);
1453  $ok = $login_item->delete_from_db();
1454  }
1455 
1456  if ($ok) {
1457  $ok = $user->delete_from_db();
1458  }
1459 
1460  // We return a record of the deleted IDs.
1461  if ($ok) {
1462  if (!isset($ret) || !is_array($ret)) {
1463  $ret = ['deleted_users' => []];
1464  if ($in_login_user) {
1465  $ret['deleted_logins'] = [];
1466  }
1467  }
1468 
1469  $ret['deleted_users'][] = $user_dump;
1470 
1471  if ($login_dump) {
1472  $ret['deleted_logins'][] = $login_dump;
1473  }
1474  }
1475  }
1476  }
1477  // OK. We have successfully deleted the users (and maybe the logins, as well). We will return the dumps of the users and logins in the function return as associative arrays.
1478 
1479  return $ret;
1480  }
1481 
1482  /***********************/
1488  protected function _handle_edit_people_post( $in_andisol_instance,
1489  $in_login_user,
1490  $in_path = [],
1491  $in_query = []
1492  ) {
1493  $ret = NULL;
1494 
1495  $login_id = (isset($in_query['login_id']) && trim($in_query['login_id'])) ? trim($in_query['login_id']) : NULL;
1496  $in_login_user = $in_login_user || (NULL != $login_id); // Supplying a login ID also means creating a new login.
1497  // If this is set, then it means that the new ID should be created with a "private" token, that is not given to the manager that creates it. Ignored, if "login_id" is not also set.
1498  $private_token = ($login_id && (isset($in_query['private_token']) && trim($in_query['private_token']))) ? TRUE : FALSE;
1499 
1500  $ret = ['new_user'];
1501  $password = NULL;
1502 
1503  if (isset($in_query['login_id'])) {
1504  unset($in_query['login_id']);
1505  }
1506 
1507  if ($private_token) {
1508  $in_query['private_token'] = TRUE;
1509  } elseif (isset($in_query['private_token'])) {
1510  unset($in_query['private_token']);
1511  }
1512 
1513  $password = isset($in_query) && is_array($in_query) && isset($in_query['password']) && trim($in_query['password']) ? trim($in_query['password']) : NULL;
1514  if (isset($in_query['password'])) {
1515  unset($in_query['password']);
1516  }
1517 
1518  if (!$password || (strlen($password) < CO_Config::$min_pw_len)) {
1519  $password = substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"), 0, CO_Config::$min_pw_len + 2);
1520  }
1521 
1522  $name = isset($in_query) && is_array($in_query) && isset($in_query['name']) && trim($in_query['name']) ? trim($in_query['name']) : NULL;
1523  if (isset($in_query['name'])) {
1524  unset($in_query['name']);
1525  }
1526 
1527  $is_manager = isset($in_query) && is_array($in_query) && isset($in_query['is_manager']);
1528  if (isset($in_query['is_manager'])) {
1529  unset($in_query['is_manager']);
1530  }
1531 
1532  $my_tokens = array_map('intval', $in_andisol_instance->get_login_item()->ids());
1533  array_shift($my_tokens); // we remove our own ID.
1534 
1535  $tokens = isset($in_query) && is_array($in_query) && isset($in_query['tokens']) && trim($in_query['tokens']) ? trim($in_query['tokens']) : NULL;
1536  if (isset($in_query['tokens'])) {
1537  unset($in_query['tokens']);
1538  }
1539 
1540  if (isset($tokens)) {
1541  $tokens_temp = array_map('intval', explode(',', $tokens));
1542  $tokens = [];
1543 
1544  if ($in_andisol_instance->god()) { // God is on the TSA Pre-Check list.
1545  $tokens = $tokens_temp;
1546  } else { // Otherwise, we need to make sure that we have only tokens that we own.
1547  // BADGER deals with this, but we trust no one.
1548  $tokens_temp = array_intersect($my_tokens, $tokens_temp);
1549  foreach ($tokens_temp as $token) {
1550  if ((1 < $token) && ($token != $in_andisol_instance->get_login_item()->id())) {
1551  $tokens[] = $token;
1552  }
1553  }
1554  }
1555 
1556  $in_query['tokens'] = implode(',', $tokens);
1557  }
1558 
1559  $read_token = isset($in_query) && is_array($in_query) && isset($in_query['read_token']) && intval($in_query['read_token']) ? intval($in_query['read_token']) : 1;
1560  if (isset($in_query['read_token'])) {
1561  unset($in_query['read_token']);
1562  }
1563 
1564  if ((0 == $read_token) || (1 == $read_token) || in_array($read_token, $my_tokens)) {
1565  $in_query['read_token'] = $read_token;
1566  }
1567 
1568  $write_token = isset($in_query) && is_array($in_query) && isset($in_query['write_token']) && intval($in_query['write_token']) ? intval($in_query['write_token']) : 0;
1569 
1570  if (isset($in_query['write_token'])) {
1571  unset($in_query['write_token']);
1572  }
1573 
1574  if (isset($write_token) && in_array($write_token, $my_tokens)) {
1575  $in_query['write_token'] = $read_token;
1576  }
1577 
1578  $user = NULL;
1579  $settings_list = $this->_build_user_mod_list($in_andisol_instance, 'POST', $in_query); // First, build up a list of the settings for the new user.
1580 
1581  if ($in_login_user) { // Create a user/login pair.
1582  // The number of personal tokens to initialize with the login.
1583  // If this is not specified, it is zero. Also, it only applies to new logins; not users.
1584  $number_of_personal_tokens = (isset($in_query['number_of_personal_tokens']) && trim($in_query['number_of_personal_tokens'])) ? intval(trim($in_query['number_of_personal_tokens'])) : 0;
1585 
1586  $password = $in_andisol_instance->create_new_user($login_id, $password, $name, $tokens, 0, $is_manager, $number_of_personal_tokens);
1587 
1588  if ($password) {
1589  $user = $in_andisol_instance->get_user_from_login_string($login_id);
1590  }
1591  } else { // Standalone user (person).
1592  $user = $in_andisol_instance->make_standalone_user();
1593  }
1594 
1595  if (isset($user) && ($user instanceof CO_User_Collection)) {
1596  $in_path[] = $user->id();
1597  $result = $this->_handle_edit_people_put($in_andisol_instance, $in_login_user, $in_path, $in_query);
1598  // We fetch the user we just modified, so we get all the changes.
1599  $user = $in_andisol_instance->get_single_data_record_by_id($user->id());
1600  $ret = Array('new_user' => $this->_get_long_user_description($user, true));
1601 
1602  if ($in_login_user && isset($password)) {
1603  $ret['new_user']['associated_login']['password'] = $password;
1604  }
1605  } else {
1606  header('HTTP/1.1 400 Failed to Create User');
1607  exit();
1608  }
1609 
1610  return $ret;
1611  }
1612 
1613  /***********************/
1619  protected function _build_user_mod_list( $in_andisol_instance,
1620  $in_http_method,
1621  $in_query = NULL
1622  ) {
1623  // <rubs hands/> Now, let's get to work...
1624  // First, build up a list of the items that we want to change.
1625 
1626  $ret = parent::_process_parameters($in_andisol_instance, $in_query);
1627 
1628  if (isset($in_query) && is_array($in_query) && count($in_query)) {
1629  // See if they want to add new child data items to each user, or remove existing ones.
1630  // We indicate adding ones via positive integers (the item IDs), and removing via negative integers (minus the item ID).
1631  if (isset($in_query['tokens'])) {
1632  $tokens_temp = array_map('intval', explode(',', $in_query['tokens']));
1633  $tokens = [];
1634 
1635  if ($in_andisol_instance->god()) { // God is on the TSA Pre-Check list.
1636  $tokens = $tokens_temp;
1637  } else { // Otherwise, we need to make sure that we have only tokens that we own.
1638  // BADGER deals with this, but we trust no one.
1639  $my_tokens = array_map('intval', $in_andisol_instance->get_login_item()->ids());
1640  $tokens_temp = array_intersect($my_tokens, $tokens_temp);
1641  foreach ($tokens_temp as $token) {
1642  if ((1 < $token) && ($token != $in_andisol_instance->get_login_item()->id())) {
1643  $tokens[] = $token;
1644  }
1645  }
1646  }
1647 
1648  $ret['tokens'] = $tokens;
1649  }
1650 
1651  // Next, we see if we want to change the password.
1652  if (isset($in_query['password']) && (strlen(trim($in_query['password'])) >= CO_Config::$min_pw_len)) {
1653  $ret['password'] = trim($in_query['password']);
1654  }
1655 
1656  // Next, we see if we want to change the surname.
1657  if (isset($in_query['surname'])) {
1658  $ret['surname'] = trim(strval($in_query['surname']));
1659  }
1660 
1661  // Next, we see if we want to change the middle name.
1662  if (isset($in_query['middle_name'])) {
1663  $ret['middle_name'] = trim(strval($in_query['middle_name']));
1664  }
1665 
1666  // Next, we see if we want to change the first name.
1667  if (isset($in_query['given_name'])) {
1668  $ret['given_name'] = trim(strval($in_query['given_name']));
1669  }
1670 
1671  // Next, we see if we want to change the prefix.
1672  if (isset($in_query['prefix'])) {
1673  $ret['prefix'] = trim(strval($in_query['prefix']));
1674  }
1675 
1676  // Next, we see if we want to change the suffix.
1677  if (isset($in_query['suffix'])) {
1678  $ret['suffix'] = trim(strval($in_query['suffix']));
1679  }
1680 
1681  // Next, we see if we want to change the nickname.
1682  if (isset($in_query['nickname'])) {
1683  $ret['nickname'] = trim(strval($in_query['nickname']));
1684  }
1685 
1686  // Next, we see if we want to change/set the login object asociated with this. You can remove an associated login object by passing in NULL or 0, here.
1687  if (isset($in_query['login_id']) && (('POST' == $in_http_method) || $in_andisol_instance->god())) { // Only God can change login IDs (unless we are creating a new user).
1688  $ret['login_id'] = abs(intval(trim($in_query['login_id'])));
1689  }
1690 
1691  // Next, look for the last three tags (the only ones we're allowed to change).
1692  if (isset($in_query['tag7'])) {
1693  $ret['tag7'] = trim(strval($in_query['tag7']));
1694  }
1695 
1696  // Next, look for the last two tags (the only ones we're allowed to change).
1697  if (isset($in_query['tag8'])) {
1698  $ret['tag8'] = trim(strval($in_query['tag8']));
1699  }
1700 
1701  if (isset($in_query['tag9'])) {
1702  $ret['tag9'] = trim(strval($in_query['tag9']));
1703  }
1704  }
1705 
1706  return $ret;
1707  }
1708 
1709  /***********************/
1715  protected function _handle_people( $in_andisol_instance,
1716  $in_path = [],
1717  $in_query = []
1718  ) {
1719  $ret = [];
1720  $login_user = isset($in_query) && is_array($in_query) && isset($in_query['login_user']); // Flag saying they are only looking for login people.
1721  $show_parents = isset($in_query) && is_array($in_query) && isset($in_query['show_parents']); // Show all places in detail, as well as the parents (applies only to GET).
1722  $show_details = $show_parents || (isset($in_query) && is_array($in_query) && isset($in_query['show_details'])); // Show all places in detail (applies only to GET).
1723  $logged_in = isset($in_query) && is_array($in_query) && isset($in_query['logged_in']) && $in_andisol_instance->manager(); // Flag that filters for only users that are logged in.
1724  $my_info = isset($in_path) && is_array($in_path) && (0 < count($in_path) && ('my_info' == $in_path[0])); // Directory that specifies we are only looking for our own info.
1725  $writeable = isset($in_query) && is_array($in_query) && isset($in_query['writeable']); // Show/list only people this user can modify.
1726 
1727  if ($logged_in) { // If we are looking for logged in users, then this should be true, Q.E.D.
1728  $login_user = true;
1729  }
1730 
1731  if ($login_user) { // Same for login_user.
1732  if (!$in_andisol_instance->logged_in()) { // You can't look for users by login, if you, yourself, are not logged in.
1733  return [];
1734  }
1735  $show_details = true;
1736  }
1737 
1738  if (isset($in_query['get_all_visible_users'])) { // The next thing we check for, is to see if this is a simple request to return the IDs and names of all visible users.
1739  $ret['get_all_visible_users'] = $in_andisol_instance->get_all_visible_users();
1740  } elseif (isset($in_query['get_all_visible_logins'])) { // The next thing we check for, is to see if this is a simple request to return the IDs, names, and login ID of all visible logins.
1741  $ret['get_all_visible_logins'] = $in_andisol_instance->get_all_visible_logins();
1742  } elseif (isset($my_info) && $my_info) { // If we are just asking after our own info, then we just send that back.
1743  if ($in_andisol_instance->logged_in()) {
1744  $user = $in_andisol_instance->current_user();
1745  if ($user instanceof CO_User_Collection) {
1746  $ret['my_info'] = $this->_get_long_user_description($user, $login_user, $show_parents);
1747  } else {
1748  header('HTTP/1.1 400 No Logged-In User');
1749  exit();
1750  }
1751  } else {
1752  header('HTTP/1.1 403 Forbidden');
1753  exit();
1754  }
1755  } elseif (isset($in_path) && is_array($in_path) && (1 < count($in_path) && ('login_ids' == $in_path[0]))) { // See if they are looking for people associated with string login IDs.
1756  // Now, we see if they are a list of integer IDs or strings (login string IDs).
1757  $login_id_list = array_map('trim', explode(',', $in_path[1]));
1758 
1759  $is_numeric = array_reduce($login_id_list, function($carry, $item){ return $carry && ctype_digit($item); }, true);
1760 
1761  $login_id_list = $is_numeric ? array_map('intval', $login_id_list) : $login_id_list;
1762 
1763  foreach ($login_id_list as $login_id) {
1764  $login_instance = $is_numeric ? $in_andisol_instance->get_login_item($login_id) : $in_andisol_instance->get_login_item_by_login_string($login_id);
1765 
1766  if (isset($login_instance) && ($login_instance instanceof CO_Security_Login)) {
1767  if (!$logged_in || ($logged_in && $login_instance->get_api_key())) { // See if they are filtering for logins.
1768  $id_string = $login_instance->login_id;
1769  $user = $in_andisol_instance->get_user_from_login_string($id_string);
1770  if (isset($user) && ($user instanceof CO_User_Collection) && (!$writeable || $user->user_can_write())) {
1771  if ($show_details) {
1772  $ret[] = $this->_get_long_user_description($user, $login_user, $show_parents);
1773  } else {
1774  $ret[] = $this->_get_short_description($user);
1775  }
1776  }
1777  }
1778  }
1779  }
1780  } elseif (isset($in_path) && is_array($in_path) && (0 < count($in_path))) { // See if they are looking for a list of individual discrete integer IDs.
1781  $user_nums = strtolower($in_path[0]);
1782 
1783  $single_user_id = (ctype_digit($user_nums) && (1 < intval($user_nums))) ? intval($user_nums) : NULL; // This will be for if we are looking only one single user.
1784  // The first thing that we'll do, is look for a list of user IDs. If that is the case, we split them into an array of int.
1785  $user_list = explode(',', $user_nums);
1786 
1787  // If we do, indeed, have a list, we will force them to be ints, and cycle through them.
1788  if ($single_user_id || (1 < count($user_list))) {
1789  $user_list = ($single_user_id ? [$single_user_id] : array_map('intval', $user_list));
1790 
1791  foreach ($user_list as $id) {
1792  if (0 < $id) {
1793  $user = $in_andisol_instance->get_single_data_record_by_id($id);
1794  if (isset($user) && ($user instanceof CO_User_Collection) && (!$writeable || $user->user_can_write())) {
1795  if (!$login_user || ($login_user && $user->has_login())) {
1796  if ($logged_in) { // If we are only looking for logged-in users, then we skip to the next one if this is not a logged-in user.
1797  $login_instance = $user->get_login_instance();
1798 
1799  if (!isset($login_instance) || !($login_instance instanceof CO_Security_Login) || !$login_instance->get_api_key()) {
1800  continue;
1801  }
1802  }
1803  if ($show_details) {
1804  $ret[] = $this->_get_long_user_description($user, $login_user, $show_parents);
1805  } else {
1806  $ret[] = $this->_get_short_description($user);
1807  }
1808  }
1809  }
1810  }
1811  }
1812  }
1813  } else { // They want the list of all of them (or a filtered list).
1814  $radius = isset($in_query) && is_array($in_query) && isset($in_query['search_radius']) && (0.0 < floatval($in_query['search_radius'])) ? floatval($in_query['search_radius']) : NULL;
1815  $longitude = isset($in_query) && is_array($in_query) && isset($in_query['search_longitude']) ? floatval($in_query['search_longitude']) : NULL;
1816  $latitude = isset($in_query) && is_array($in_query) && isset($in_query['search_latitude']) ? floatval($in_query['search_latitude']) : NULL;
1817  $search_page_size = isset($in_query) && is_array($in_query) && isset($in_query['search_page_size']) ? abs(intval($in_query['search_page_size'])) : 0; // Ignored for discrete IDs. This is the size of a page of results (1-based result count. 0 is no page size).
1818  $search_page_number = isset($in_query) && is_array($in_query) && isset($in_query['search_page_number']) ? abs(intval($in_query['search_page_number'])) : 0; // Ignored for discrete IDs, or if search_page_size is 0. The page we are interested in (0-based. 0 is the first page).
1819  $search_name = isset($in_query) && is_array($in_query) && isset($in_query['search_name']) ? trim($in_query['search_name']) : NULL; // Search in the object name.
1820  $search_surname = isset($in_query) && is_array($in_query) && isset($in_query['search_surname']) ? trim($in_query['search_surname']) : NULL; // Search in the surname.
1821  $search_middle_name = isset($in_query) && is_array($in_query) && isset($in_query['search_middle_name']) ? trim($in_query['search_middle_name']) : NULL; // Search in the middle name.
1822  $search_given_name = isset($in_query) && is_array($in_query) && isset($in_query['search_given_name']) ? trim($in_query['search_given_name']) : NULL; // Search in the first name.
1823  $search_nickname = isset($in_query) && is_array($in_query) && isset($in_query['search_nickname']) ? trim($in_query['search_nickname']) : NULL; // Search in the nickname.
1824  $search_prefix = isset($in_query) && is_array($in_query) && isset($in_query['search_prefix']) ? trim($in_query['search_prefix']) : NULL; // Search in the prefix.
1825  $search_suffix = isset($in_query) && is_array($in_query) && isset($in_query['search_suffix']) ? trim($in_query['search_suffix']) : NULL; // Search in the suffix.
1826  $search_tag7 = isset($in_query) && is_array($in_query) && isset($in_query['search_tag7']) ? trim($in_query['search_tag7']) : NULL; // Search in the tag.
1827  $search_tag8 = isset($in_query) && is_array($in_query) && isset($in_query['search_tag8']) ? trim($in_query['search_tag8']) : NULL; // Search in the tag.
1828  $search_tag9 = isset($in_query) && is_array($in_query) && isset($in_query['search_tag9']) ? trim($in_query['search_tag9']) : NULL; // Search in the tag.
1829 
1830  $location_search = NULL;
1831  $string_search = ($search_name !== NULL)
1832  || ($search_surname !== NULL)
1833  || ($search_middle_name !== NULL)
1834  || ($search_given_name !== NULL)
1835  || ($search_nickname !== NULL)
1836  || ($search_prefix !== NULL)
1837  || ($search_suffix !== NULL)
1838  || ($search_tag7 !== NULL)
1839  || ($search_tag8 !== NULL)
1840  || ($search_tag9 !== NULL);
1841 
1842  // We make sure that we puke if they give us a bad distance search.
1843  if (isset($radius) && isset($longitude) && isset($latitude)) {
1844  $location_search = Array('radius' => $radius, 'longitude' => $longitude, 'latitude' => $latitude);
1845  } elseif (isset($radius) || isset($longitude) || isset($latitude)) {
1846  header('HTTP/1.1 400 Incomplete Distance Search');
1847  exit();
1848  }
1849 
1850  $userlist = [];
1851  if ((isset($location_search) && is_array($location_search) && (3 == count($location_search))) || (0 < $search_page_size) || $string_search) {
1852  $class_search = Array('%_User_Collection', 'use_like' => 1);
1853  $search_array['access_class'] = $class_search;
1854  $search_array['location'] = $location_search;
1855  if (isset($search_name)) {
1856  $search_array['name'] = Array($search_name, 'use_like' => 1);
1857  }
1858 
1859  $tags_array = [NULL];
1860 
1861  $tags_array[] = isset($search_surname) ? $search_surname : NULL;
1862  $tags_array[] = isset($search_middle_name) ? $search_middle_name : NULL;
1863  $tags_array[] = isset($search_given_name) ? $search_given_name : NULL;
1864  $tags_array[] = isset($search_nickname) ? $search_nickname : NULL;
1865  $tags_array[] = isset($search_prefix) ? $search_prefix : NULL;
1866  $tags_array[] = isset($search_suffix) ? $search_suffix : NULL;
1867  $tags_array[] = isset($search_tag7) ? $search_tag7 : NULL;
1868  $tags_array[] = isset($search_tag8) ? $search_tag8 : NULL;
1869  $tags_array[] = isset($search_tag9) ? $search_tag9 : NULL;
1870 
1871  $has_tags = false;
1872  foreach ($tags_array as $tag) {
1873  if (NULL !== $tag) {
1874  $has_tags = true;
1875  break;
1876  }
1877  }
1878 
1879  if ($has_tags) {
1880  $tags_array['use_like'] = 1;
1881  $search_array['tags'] = $tags_array;
1882  }
1883 
1884  $userlist = $in_andisol_instance->generic_search($search_array, false, $search_page_size, $search_page_number, $writeable);
1885  } else {
1886  $userlist = $in_andisol_instance->get_all_users();
1887  }
1888 
1889  if (isset($userlist) && is_array($userlist) && count($userlist)) {
1890  foreach ($userlist as $user) {
1891  if (isset($user) && ($user instanceof CO_User_Collection) && (!$writeable || $user->user_can_write())) {
1892  if (!$login_user || ($login_user && $user->has_login())) {
1893  if ($logged_in) { // If we are only looking for logged-in users, then we skip to the next one if this is not a logged-in user.
1894  $login_instance = $user->get_login_instance();
1895 
1896  if (!isset($login_instance) || !($login_instance instanceof CO_Security_Login) || !$login_instance->get_api_key()) {
1897  continue;
1898  }
1899  }
1900  if ($show_details) {
1901  $ret[] = $this->_get_long_user_description($user, $login_user, $show_parents);
1902  } else {
1903  $ret[] = $this->_get_short_description($user);
1904  }
1905  }
1906  }
1907  }
1908 
1909  if ($location_search) {
1910  $ret['search_location'] = $location_search;
1911  }
1912  }
1913  }
1914 
1915  return $ret;
1916  }
1917 
1918  /***********************/
1922  public function plugin_name() {
1923  return 'people';
1924  }
1925 
1926  /***********************/
1932  static public function classes_managed() {
1933  return ['CO_User_Collection', 'CO_Login_Manager', 'CO_Cobra_login', 'CO_Security_Login'];
1934  }
1935 
1936  /***********************/
1942  public function process_command( $in_andisol_instance,
1943  $in_http_method,
1944  $in_response_type,
1945  $in_path = [],
1946  $in_query = []
1947  ) {
1948  $ret = [];
1949  // For the default (no user ID, login or personal ID), we simply return a list of commands. We also only allow GET to do this.
1950  if (0 == count($in_path)) {
1951  if ('GET' == $in_http_method) {
1952  $ret = ['people'];
1953  if ($in_andisol_instance->logged_in()) {
1954  $ret[] = 'logins';
1955  $ret[] = 'personal_tokens';
1956  }
1957  } else {
1958  header('HTTP/1.1 400 Incorrect HTTP Request Method');
1959  exit();
1960  }
1961  } else {
1962  $main_command = $in_path[0]; // Get the main command.
1963  $show_parents = isset($in_query) && is_array($in_query) && isset($in_query['show_parents']); // Show all users/logins in detail, as well as the parents (applies only to GET or DELETE, and not for personal tokens).
1964 
1965  array_shift($in_path);
1966 
1967  switch (strtolower($main_command)) {
1968  case 'people':
1969  if ('GET' == $in_http_method) {
1970  $ret['people'] = $this->_handle_people($in_andisol_instance, $in_path, $in_query);
1971  } elseif ($in_andisol_instance->logged_in()) { // Must be logged in to be non-GET.
1972  $ret['people'] = $this->_handle_edit_people($in_andisol_instance, $in_http_method, $in_path, $in_query, $show_parents);
1973  } else {
1974  if (!$in_andisol_instance->logged_in()) {
1975  header('HTTP/1.1 403 Unauthorized');
1976  } else {
1977  header('HTTP/1.1 400 Incorrect HTTP Request Method');
1978  }
1979  exit();
1980  }
1981  break;
1982  case 'logins':
1983  if ('GET' == $in_http_method) {
1984  $ret['logins'] = $this->_handle_logins($in_andisol_instance, $in_path, $in_query);
1985  } else {
1986  $ret['logins'] = $this->_handle_edit_logins($in_andisol_instance, $in_http_method, $in_path, $in_query, $show_parents);
1987  }
1988  break;
1989  case 'personal_tokens':
1990  if ('GET' == $in_http_method) {
1991  $ret['personal_tokens'] = $this->_handle_personal_ids($in_andisol_instance, $in_path, $in_query);
1992  } else {
1993  $ret['personal_tokens'] = $this->_handle_edit_personal_ids($in_andisol_instance, $in_http_method, $in_path, $in_query);
1994  }
1995  break;
1996  }
1997  }
1998 
1999  return $this->_condition_response($in_response_type, $ret);
2000  }
2001 }
_handle_personal_ids( $in_andisol_instance, $in_path=[], $in_query=[])
_handle_edit_people_post( $in_andisol_instance, $in_login_user, $in_path=[], $in_query=[])
_handle_edit_logins( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[], $in_show_parents=false)
_handle_logins( $in_andisol_instance, $in_path=[], $in_query=[])
process_command( $in_andisol_instance, $in_http_method, $in_response_type, $in_path=[], $in_query=[])
_get_long_description( $in_login_object, $ignored=false)
_handle_edit_people_put( $in_andisol_instance, $in_login_user, $in_path=[], $in_query=[])
_handle_edit_logins_put( $in_andisol_instance, $in_logins_to_edit, $in_query=[])
_get_short_description( $in_object, $in_additional_info=false)
_build_login_mod_list( $in_andisol_instance, $in_query=NULL)
_get_long_user_description( $in_user_object, $in_with_login_info=false, $in_show_parents=false)
_handle_edit_logins_post( $in_andisol_instance, $in_path=[], $in_query=[])
_build_user_mod_list( $in_andisol_instance, $in_http_method, $in_query=NULL)
_handle_people( $in_andisol_instance, $in_path=[], $in_query=[])
_handle_edit_logins_delete( $in_andisol_instance, $in_logins_to_edit, $in_query=[], $in_also_delete_user=false, $in_show_parents=false)
_handle_edit_personal_ids( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[])
_handle_edit_people( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[], $in_show_parents=false)
_handle_edit_people_delete( $in_andisol_instance, $in_login_user, $in_path=[], $in_query=[], $in_show_parents=false)