BAOBAB
CO_Basalt Class Reference
Inheritance diagram for CO_Basalt:
Collaboration diagram for CO_Basalt:

Public Member Functions

 __construct ()
 
 get_plugin_names ()
 
 valid ()
 
 logged_in ()
 
 plugin_name ()
 
 process_command ( $in_andisol_instance, $in_http_method, $in_response_type, $in_path=[], $in_query=[])
 

Static Public Member Functions

static classes_managed ()
 

Public Attributes

 $version
 The version indicator. More...
 
 $error
 Any errors that occured are kept here. More...
 

Protected Member Functions

 _process_basalt_parameters ()
 
 _process_command ()
 
 _process_token_command ( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[])
 
 _process_serverinfo_command ( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[])
 
 _process_ping_command ( $in_andisol_instance, $in_path=[])
 
 _process_baseline_command ( $in_andisol_instance, $in_http_method, $in_command, $in_path=[], $in_query=[])
 
 _baseline_fetch_backup ( $in_andisol_instance)
 
 _baseline_bulk_loader ()
 
 _process_bulk_row ( $in_row_data)
 
 _get_xsd ()
 
- Protected Member Functions inherited from A_CO_Basalt_Plugin
 _get_short_description ( $in_object)
 
 _get_long_description ( $in_object, $in_show_parents=false)
 
 _get_xml_header ()
 
 _get_xsd_header ()
 
 _process_xsd ( $in_schema_file_path)
 
 _condition_response ( $in_response_type, $in_response_as_associative_array=NULL)
 
 _get_child_ids ( $in_object)
 
 _get_child_handler_data ( $in_object)
 
 _process_parameters ( $in_andisol_instance, $in_query)
 

Static Protected Member Functions

static _extract_csv_data ( $in_text_data)
 
static _output_one_line ( $in_line, $in_header_row)
 
- Static Protected Member Functions inherited from A_CO_Basalt_Plugin
static _get_handler ( $in_classname)
 
static _server_url ()
 
static _array2xml ( $in_array)
 

Protected Attributes

 $_andisol_instance
 This contains the instance of ANDISOL used by this instance. More...
 
 $_path
 This array will contain any path components that are received via GET, PUT, POST or DELETE. More...
 
 $_vars
 This associative array will contain any query variables that are received via GET, PUT, POST or DELETE. More...
 
 $_request_type
 
 $_response_type
 This is the reponse type. It is 'json', 'xml' or 'xsd'. More...
 
 $_plugin_selector
 This will be a lowercase string, denoting the plugin selected for the operation. More...
 

Additional Inherited Members

- Static Protected Attributes inherited from A_CO_Basalt_Plugin
static $_s_cached_list = NULL
 This will contain caches of our handler list. More...
 

Detailed Description

BASALT is the principal "interface" class for BAOBAB. It can be extended by writing simple PHP "plugins," and comes with four "default" ones: "people", "places" and "things". "baseline" is a "host" pseudo-plugin.

Definition at line 55 of file co_basalt.class.php.

Constructor & Destructor Documentation

◆ __construct()

CO_Basalt::__construct ( )

Constructor

Definition at line 952 of file co_basalt.class.php.

952  {
953  $this->version = __BASALT_VERSION__;
954  $this->error = NULL;
955  $this->_andisol_instance = NULL;
956  try {
957  // IIS puts "off" in the HTTPS field, so we need to test for that.
958  $https = ((!empty($_SERVER['HTTPS']) && (($_SERVER['HTTPS'] !== 'off') || (intval($_SERVER['SERVER_PORT']) == 443)))) ? true : false;
959  if ((CO_CONFIG_HTTPS_ALL > CO_Config::$ssl_requirement_level) || $https) {
961  // This is a test, to see whether or not we should use auth parameters (fastCGI).
962  if ((1 == count($this->_path)) && ('use_auth_params' == $this->_path[0])) {
963  exit('cgi' == substr(php_sapi_name(), 0, 3) ? '1' : '0');
964  // If this is a login, we do nothing else. We simply handle the login.
965  } elseif ((1 == count($this->_path)) && ('login' == $this->_path[0])) {
966  if (isset($this->_vars) && isset($this->_vars['login_id']) && isset($this->_vars['password'])) {
967  // We have the option (default on) of requiring TLS/SSL for logging in, so we check for that now.
968  if ($https || (CO_CONFIG_HTTPS_OFF == CO_Config::$ssl_requirement_level)) {
969  $login_id = $this->_vars['login_id'];
970  $password = $this->_vars['password'];
971 
972  // See if we have our validator in place.
973  if (method_exists('CO_Config', 'call_login_validator_function')) {
974  if (!CO_Config::call_login_validator_function($login_id, $password, $_SERVER)) {
975  header('HTTP/1.1 403 Unauthorized Login');
976  exit();
977  }
978  }
979 
980  // We do a simple login. This will also generate an API key, which is the only response to this command.
981  $andisol_instance = new CO_Andisol($login_id, '', $password);
982 
983  if (isset($andisol_instance) && ($andisol_instance instanceof CO_Andisol) && $andisol_instance->logged_in()) {
984  if (method_exists('CO_Config', 'call_log_handler_function')) {
985  CO_Config::call_log_handler_function($andisol_instance, $_SERVER);
986  }
987  $login_item = $andisol_instance->get_login_item();
988 
989  // If we are logging in, we shortcut the process, and simply return the API key.
990  if (isset($login_item) && ($login_item instanceof CO_Security_Login)) {
991  $api_key = $login_item->get_api_key();
992  // From now on, in order to access the login resources, you'll need to include the API key in the username/password fields.
993  if (isset($api_key)) {
994  echo($api_key);
995  } else {
996  header('HTTP/1.1 403 Unauthorized Login');
997  }
998  } else {
999  header('HTTP/1.1 403 Unauthorized Login');
1000  }
1001  } else {
1002  header('HTTP/1.1 403 Unauthorized Login');
1003  }
1004  } else {
1005  header('HTTP/1.1 401 SSL Connection Required');
1006  }
1007  } else {
1008  header('HTTP/1.1 401 Credentials Required');
1009  }
1010 
1011  exit();
1012  } elseif ((1 == count($this->_path)) && ('logout' == $this->_path[0])) { // See if the user wants to log out a session.
1013  $server_secret = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : NULL;
1014  $api_key = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : NULL;
1015 
1016  if (!$server_secret || !$api_key) {
1017  $auth = explode('&', $_SERVER['QUERY_STRING']);
1018  foreach ($auth as $query) {
1019  $exp = explode('=', $query);
1020  if ('login_server_secret' == $exp[0]) {
1021  $server_secret = trim($exp[1]);
1022  } elseif ('login_api_key' == $exp[0]) {
1023  $api_key = trim($exp[1]);
1024  }
1025  }
1026  }
1027 
1028  // See if an SSL connection is required.
1029  if ($https || (CO_CONFIG_HTTPS_LOGGED_IN_ONLY > CO_Config::$ssl_requirement_level)) {
1030  // If we don't have a valid API key/Server Secret pair, we scrag the process.
1031  if(!(isset($api_key) && $api_key && ($server_secret == Co_Config::server_secret()))) {
1032  header('HTTP/1.1 403 Cannot Logout Without Valid Credentials');
1033  } else {
1034  $andisol_instance = new CO_Andisol('', '', '', $api_key);
1035 
1036  if (isset($andisol_instance) && ($andisol_instance instanceof CO_Andisol) && $andisol_instance->logged_in()) {
1037  if (method_exists('CO_Config', 'call_log_handler_function')) {
1038  CO_Config::call_log_handler_function($andisol_instance, $_SERVER);
1039  }
1040 
1041  $login_item = $andisol_instance->get_login_item();
1042 
1043  // We "log out" by clearing the API key.
1044  if (isset($login_item) && ($login_item instanceof CO_Security_Login)) {
1045  if ($login_item->clear_api_key()) {
1046  header('HTTP/1.1 205 Logout Successful');
1047  } else { // This will probably never happen, but belt and suspenders...
1048  header('HTTP/1.1 200 Logout Unneccessary');
1049  }
1050  } else { // This will probably never happen, but belt and suspenders...
1051  header('HTTP/1.1 500 Internal Server Error');
1052  }
1053  } else {
1054  header('HTTP/1.1 403 Unauthorized Login');
1055  }
1056  }
1057  } else {
1058  header('HTTP/1.1 401 SSL Connection Required');
1059  }
1060 
1061  exit();
1062  } else { // Handle the rest of the requests here.
1063  // Look for authentication.
1064 
1065  $server_secret = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : NULL; // Supplied to the client by the Server Admin.
1066  $api_key = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : NULL; // Generated by the server for this session.
1067 
1068  if (!$server_secret || !$api_key) {
1069  $auth = explode('&', $_SERVER['QUERY_STRING']);
1070  foreach ($auth as $query) {
1071  $exp = explode('=', $query);
1072  if ('login_server_secret' == $exp[0]) {
1073  $server_secret = trim($exp[1]);
1074  } elseif ('login_api_key' == $exp[0]) {
1075  $api_key = trim($exp[1]);
1076  }
1077  }
1078  }
1079 
1080  // If we don't have a valid API key/Server Secret pair, we just forget about API keys.
1081  if(!(isset($api_key) && $api_key && ($server_secret == Co_Config::server_secret()))) {
1082  $api_key = NULL;
1083  }
1084 
1085  $https_requirement = true;
1086 
1087  // Make sure we are HTTPS, or SSL is not required.
1088  switch (CO_Config::$ssl_requirement_level) {
1089  case CO_CONFIG_HTTPS_ALL:
1090  // Yeah, it's required.
1091  break;
1092 
1093  case CO_CONFIG_HTTPS_LOGGED_IN_ONLY:
1094  // Only if we have an authentication header.
1095  $https_requirement = (NULL != $api_key);
1096  break;
1097 
1098  default:
1099  // Not necessary if we are login only or off.
1100  $https_requirement = false;
1101  break;
1102  }
1103 
1104  if ($https || !$https_requirement) {
1105  $andisol_instance = new CO_Andisol('', '', '', $api_key);
1106  if (isset($andisol_instance) && ($andisol_instance instanceof CO_Andisol)) {
1107  if (method_exists('CO_Config', 'call_log_handler_function')) {
1108  CO_Config::call_log_handler_function($andisol_instance, $_SERVER);
1109  }
1110  $this->_andisol_instance = $andisol_instance;
1111  } else {
1112  header('HTTP/1.1 500 Internal Server Error');
1113  exit();
1114  }
1115  } else {
1116  header('HTTP/1.1 401 SSL Connection Required');
1117  exit();
1118  }
1119  }
1120  } else {
1121  header('HTTP/1.1 401 SSL Connection Required');
1122  exit();
1123  }
1124  // OK. By the time we get here, we are either logged in, or not logged in, and have a valid ANDISOL instance. We're ready to go. Put on our shades. We're on a mission for Glod.
1125  $this->_process_command();
1126  } catch (Exception $e) {
1127  header('HTTP/1.1 500 Internal Server Error');
1128  exit();
1129  }
1130  }
const __BASALT_VERSION__
_process_basalt_parameters()

References __BASALT_VERSION__, _process_basalt_parameters(), and _process_command().

Here is the call graph for this function:

Member Function Documentation

◆ _baseline_bulk_loader()

CO_Basalt::_baseline_bulk_loader ( )
protected

This is a special processing routine that is used to facilitate bulk-loading a BAOBAB server.

The caller must be logged in as a "God" admin, and they upload a CSV file. This file will have certain columns that will be used by this routine to instantiate new records.

This is only of of two Baseline commands called via 'POST'.

Returns
the new records, in complete form.

Definition at line 774 of file co_basalt.class.php.

774  {
775  $ret = NULL;
776  set_time_limit(3600); // Give us plenty of time.
777 
778  // Have to be "God," and the variable in the config needs to be set.
779  if ($this->_andisol_instance->god() && CO_Config::$enable_bulk_upload) {
780  if ('POST' == $this->_request_type) { // We must be a POST. There is only the 'loader' command, no query parameters, and no resource path. Just a simple POST, authenticated as "God," and a 'payload' of a CSV file.
781  if (isset($_FILES['payload']) && (!isset($_FILES['payload']['error']) || is_array($_FILES['payload']['error']))) { // Look for any errors in the payload.
782  header('HTTP/1.1 400 '.print_r($_FILES['payload']['error'], true));
783  exit();
784  } elseif (isset($_FILES['payload'])) {
785  $file_data = base64_decode(file_get_contents($_FILES['payload']['tmp_name'])); // We extract the CSV data. It should have been sent as Base64-encoded UTF-8 text, so we decode it first.
786 
787  $csv_data = self::_extract_csv_data($file_data);
788  if (isset($csv_data) && is_array($csv_data) && count($csv_data)) {
789  $ret = ['bulk_upload' => []]; // Prep a response.
790  $records = [];
791  $data_records = [];
792  $security_ids = [];
793  $data_ids = [];
794 
795  // This complex little dance, is so that we make sure that any tokens that used the old ID scheme are moved to the new scheme.
796  foreach ($csv_data as $row) {
797  $in_id = intval($row['id']);
798  $row_result = ['input_id' => $in_id];
799  $new_record = $this->_process_bulk_row($row);
800  // Here's where we track the old scheme. We make a record of each security node that we read.
801  if ($new_record instanceof CO_Security_Node) {
802  $security_ids[$in_id] = intval($new_record->id()); // This is a translation table for the IDs. We save all new security records; whether or not they are a login, as every record is a token.
803  } else {
804  $data_ids[$in_id] = intval($new_record->id()); // We do the same for data IDs.
805  }
806 
807  $records[] = $new_record; // Save the record.
808  $row_result['access_class'] = get_class($new_record);
809  $row_result['output_id'] = $new_record->id();
810  $ret['bulk_upload'][] = $row_result;
811  }
812 
813  // After we're done, we go back through the records, looking for ones with tokens. We then translate each set of tokens.
814  foreach ($records as $object) {
815  if (method_exists($object, 'ids')) { // We look at the token properties of security IDs.
816  $ids = $object->ids();
817  if (isset($ids) && is_array($ids) && count($ids)) { // Look for tokens.
818  $new_ids = [];
819 
820  foreach ($ids as $id) {
821  // This has the added benefit of removing any ones that don't apply to the dataset.
822  if (isset($security_ids[$id]) && (1 < $security_ids[$id])) {
823  $new_ids[] = $security_ids[$id];
824  }
825  }
826 
827  // Replace the object's IDs with the new ones.
828  $object->set_ids($new_ids);
829  }
830  }
831 
832  if (method_exists($object, 'owner_id')) { // We look to see if there is an "owner" record column.
833  $id = $object->owner_id(); // If so, we translate that.
834  if (isset($data_ids[$id]) && (1 < $data_ids[$id])) {
835  $object->set_owner_id(intval($data_ids[$id]));
836  }
837  }
838 
839  $context = $object->context; // Get any context.
840 
841  if (method_exists($object, 'children_ids')) { // We look to see if there is an "owner" record column.
842  $old_ids = $object->children_ids(true);
843  if (isset($old_ids) && is_array($old_ids) && count($old_ids)) {
844  $object->deleteAllChildren();
845  $new_ids = [];
846  foreach ($old_ids as $id) {
847  if (isset($data_ids[$id]) && (1 < $data_ids[$id])) {
848  $new_ids[] = intval($data_ids[$id]);
849  }
850  }
851 
852  if (isset($new_ids) && is_array($new_ids) && count($new_ids)) {
853  if (!$object->set_children_ids($new_ids)) {
854  header('HTTP/1.1 500 Internal Server Error');
855  exit();
856  }
857  }
858  }
859  }
860 
861  if ($object instanceof CO_User_Collection) {
862  $old_id = intval($object->tags()[0]);
863  $new_id = $security_ids[$old_id];
864 
865  if ($new_id) {
866  $object->set_tag(0, $new_id);
867  }
868  }
869 
870  $read = $object->read_security_id;
871 
872  if (1 < $read) {
873  $read = $security_ids[$read];
874  }
875 
876  // All objects have read and write tokens that need to be translated.
877  $object->set_read_security_id($read);
878  if (0 < $object->write_security_id) {
879  $object->set_write_security_id($security_ids[$object->write_security_id]);
880  } else {
881  $object->set_write_security_id(-1);
882  }
883 
884  if (!$object->clear_batch_mode()) {
885  header('HTTP/1.1 500 Internal Server Error');
886  exit();
887  }
888  }
889  } else {
890  header('HTTP/1.1 400 Invalid Bulk Data');
891  exit();
892  }
893  }
894  } else {
895  header('HTTP/1.1 400 Improper HTTP Method');
896  exit();
897  }
898  } else {
899  header('HTTP/1.1 403 Unauthorized User');
900  exit();
901  }
902  return $ret;
903  }
_process_bulk_row( $in_row_data)
static _extract_csv_data( $in_text_data)

References _extract_csv_data(), and _process_bulk_row().

Referenced by _process_baseline_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _baseline_fetch_backup()

CO_Basalt::_baseline_fetch_backup (   $in_andisol_instance)
protected

This is a special "God Only" method that fetches a backup of the entire set of databases as a CSV dump. It directly outputs CSV data, and bypasses the return type filtering.

Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases.

Definition at line 734 of file co_basalt.class.php.

735  {
736  $ret = NULL;
737  set_time_limit(3600); // Give us plenty of time.
738 
739  // Have to be "God," and the variable in the config needs to be set.
740  if ($in_andisol_instance->god()) {
741  $backup = $in_andisol_instance->fetch_backup();
742 
743  if (isset($backup) && is_array($backup) && (2 == count($backup)) && isset($backup['security']) && is_array($backup['security']) && count($backup['security']) && isset($backup['data']) && is_array($backup['data']) && count($backup['data'])) {
744  $header_row = ['id','api_key','login_id','access_class','last_access','read_security_id','write_security_id','object_name','access_class_context','owner','longitude','latitude','tag0','tag1','tag2','tag3','tag4','tag5','tag6','tag7','tag8','tag9','ids','payload'];
745  header('Content-Type: text/csv');
746  echo(implode(',', $header_row)."\n");
747  foreach ($backup['security'] as $line) {
748  self::_output_one_line($line, $header_row);
749  }
750  foreach ($backup['data'] as $line) {
751  self::_output_one_line($line, $header_row);
752  }
753  exit();
754  } else {
755  header('HTTP/1.1 500 Internal Server Error');
756  exit();
757  }
758  } else {
759  header('HTTP/1.1 403 Unauthorized User');
760  exit();
761  }
762  }
static _output_one_line( $in_line, $in_header_row)

References _output_one_line().

Referenced by _process_baseline_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _extract_csv_data()

static CO_Basalt::_extract_csv_data (   $in_text_data)
staticprotected
Returns
CSV data, as an indexed array of rows, with each row being an associative array. No header.
Parameters
$in_text_dataREQUIRED: The text data to be parsed as new records for the databases.

Definition at line 80 of file co_basalt.class.php.

81  {
82  $csv_array = [];
83  $in_text_data = explode("\n", $in_text_data);
84  if (isset($in_text_data) && is_array($in_text_data) && (1 < count($in_text_data))) {
85  $keys = str_getcsv(array_shift($in_text_data));
86  foreach ($in_text_data as $row) {
87  $row_temp = str_getcsv($row);
88  $row = [];
89  foreach ($row_temp as $element) {
90  if (('"NULL"' == $element) || ('NULL' == $element) || ("'NULL'" == $element) || !trim($element)) {
91  $element = NULL;
92  }
93 
94  $row[] = $element;
95  }
96  if (count($row) == count($keys)) {
97  $row = array_combine($keys, $row);
98  $csv_array[] = $row;
99  }
100  }
101  } else {
102  header('HTTP/1.1 400 Invalid Bulk Data');
103  exit();
104  }
105 
106  return $csv_array;
107  }

Referenced by _baseline_bulk_loader().

Here is the caller graph for this function:

◆ _get_xsd()

CO_Basalt::_get_xsd ( )
protected

This returns the schema for this plugin as XML XSD.

Returns
XML, containing the schema for this plugin's responses. The schema needs to be comprehensive.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 940 of file co_basalt.class.php.

940  {
941  return $this->_process_xsd(dirname(__FILE__).'/schema.xsd');
942  }
_process_xsd( $in_schema_file_path)

References A_CO_Basalt_Plugin\_process_xsd().

Here is the call graph for this function:

◆ _output_one_line()

static CO_Basalt::_output_one_line (   $in_line,
  $in_header_row 
)
staticprotected

This static routine formats one line to a CSV string, then outputs it.

Parameters
$in_lineREQUIRED: The data line, as an associative array.
$in_header_rowRequired: The header row, as an array of strings.

Definition at line 113 of file co_basalt.class.php.

115  {
116  $empty_array = array_fill(0, count($in_header_row), 'NULL');
117  $template = array_combine($in_header_row, $empty_array);
118 
119  // What we do, is go through each component of the line, format it for CSV, then add it to the "template" array.
120  foreach ($in_line as $key => $value) {
121  if (!trim($value) || ('api_key' == $key)) { // We don't back up API keys or empty strings.
122  $value = 'NULL';
123  } else {
124  // Massage for proper CSV format.
125  $needs_quotes = preg_match('|[\s",]|', $value);
126  $value = str_replace("'", "''", $value);
127  $value = str_replace('"', '""', $value);
128  $value = str_replace('\\""', '""', $value);
129  $value = str_replace('\\\\', '\\', $value);
130  if ($needs_quotes) {
131  $value = "\"$value\"";
132  }
133  }
134 
135  $template[$key] = $value;
136  }
137 
138  // Send it out.
139  echo(implode(',', $template)."\n");
140  }

Referenced by _baseline_fetch_backup().

Here is the caller graph for this function:

◆ _process_basalt_parameters()

CO_Basalt::_process_basalt_parameters ( )
protected

This method goes through the passed-in REST query parameters and request paths, and sets up our local instance property with the decoded versions. At the end of this method, the internal $_path property will be an array, containing path components, and, if provided, the $_vars property will have any query parameters. If provided, the query array will be an associative array, with the key being the query element key, and the value being its value. If a query element is provided only as a key, then its value will be set to true.

Definition at line 149 of file co_basalt.class.php.

149  {
150  $paths = isset($_SERVER['PATH_INFO']) ? explode("/", substr($_SERVER['PATH_INFO'], 1)) : [];
151  $query = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : NULL;
152  $path_final = [];
153  $vars_final = [];
154  $this->_path = [];
155  $this->_vars = [];
156  $this->_response_type = NULL;
157  $this->_plugin_selector = NULL;
158 
159  $this->_request_type = strtoupper(trim($_SERVER['REQUEST_METHOD']));
160 
161  // Look to see if we are doing a login. In that case, we only grab a couple of things.
162  if ((1 < count($paths)) || (isset($paths[0]) && (('use_auth_params' == $paths[0]) || ('login' == $paths[0]) || ('logout' == $paths[0])))) { // We need at least the response and plugin types. Login and Logout get special handling.
163  $response_type = strtolower(trim($paths[0]));
164 
165  if ('use_auth_params' == $response_type) {
166  $this->_path = Array('use_auth_params');
167  } elseif ('login' == $response_type) {
168  $query = explode('&', $query);
169  $this->_path = Array('login');
170  if (isset($query) && is_array($query) && (2 == count($query))) {
171  $vars_final = [];
172 
173  foreach ($query as $param) {
174  // Now, see if we have a bunch of parameters.
175  $key = trim($param);
176  $value = NULL;
177 
178  $parts = explode('=', $param, 2);
179  if (1 < count($parts)) {
180  $key = trim($parts[0]);
181  $value = trim($parts[1]);
182  }
183 
184  if ($key) {
185  if (!isset($value) || !$value) {
186  $value = true;
187  }
188 
189  // remember that if we repeat the key, the first value is overwritten by the second (or third, or so on).
190  $vars_final[$key] = $value;
191  }
192  }
193  $this->_vars = $vars_final;
194  } else {
195  header('HTTP/1.1 403 Unauthorized Login');
196  exit();
197  }
198  } elseif ('logout' == $response_type) { // We simply ignore anything else for logout.
199  $this->_path = Array('logout');
200  } else { // We handle the rest
201  // Get the response type.
202  if (('json' == $response_type) || ('xml' == $response_type) || ('xsd' == $response_type) || ('csv' == $response_type)) {
203  array_shift($paths);
204 
205  $this->_response_type = $response_type;
206 
207  $plugin_selector = strtolower(trim($paths[0]));
208 
209  // Make sure that we are calling a valid plugin.
210  if (in_array($plugin_selector, $this->get_plugin_names())) {
211  $vars_final = [];
212 
213  $this->_plugin_selector = $plugin_selector;
214 
215  array_shift($paths);
216 
217  // We now trim the strings in the remaining paths, and make sure that we don't have any empties.
218  $this->_path = array_filter(array_map('trim', $paths), function($i){return '' != $i;});
219 
220  // Next, we examine any query parameters.
221  $query = explode('&', $query);
222 
223  if (isset($query) && is_array($query) && count($query)) {
224  foreach ($query as $param) {
225  // Now, see if we have a bunch of parameters.
226  $key = trim($param);
227  $value = NULL;
228 
229  $parts = explode('=', $param, 2);
230  if (1 < count($parts)) {
231  $key = trim($parts[0]);
232  $value = urldecode(trim($parts[1]));
233  }
234 
235  if ($key) {
236  if (!isset($value)) {
237  $value = true;
238  }
239 
240  // remember that if we repeat the key, the first value is overwritten by the second (or third, or so on).
241  $vars_final[$key] = $value;
242  }
243  }
244  }
245 
246  $file_data = '';
247 
248  if (!isset($vars_final['remove_payload'])) { // If they did not specify a payload, maybe they want one removed?
249  // POST is handled differently from PUT. POST gets proper background handling, while PUT needs a very raw approach.
250  if ('POST' == $this->_request_type) {
251  if (isset($_FILES['payload']) && (!isset($_FILES['payload']['error']) || is_array($_FILES['payload']['error']))) {
252  header('HTTP/1.1 400 '.print_r($_FILES['payload']['error'], true));
253  exit();
254  } elseif (isset($_FILES['payload'])) {
255  $file_data = file_get_contents($_FILES['payload']['tmp_name']);
256  }
257  } elseif ('PUT' == $this->_request_type) {
258  // See if they have sent any data to us via the standard HTTP channel (PUT).
259  $put_data = fopen('php://input', 'r');
260  if (isset($put_data) && $put_data) {
261  while ($data = fread($put_data, 2048)) { // Read it in 2K chunks.
262  $file_data .= $data;
263  }
264  fclose($put_data);
265  }
266  }
267 
268  // This can only go to payload.
269  if (isset($file_data) && $file_data) {
270  $vars_final['payload'] = base64_decode($file_data);
271  } elseif (isset ($vars_final['payload'])) {
272  // See if the payload is already base64.
273  if (base64_encode(base64_decode($vars_final['payload'])) == $vars_final['payload']) {
274  $vars_final['payload'] = base64_decode($vars_final['payload']);
275  }
276  }
277  }
278 
279  $this->_vars = $vars_final;
280  } else {
281  header('HTTP/1.1 400 Unsupported or Missing Plugin');
282  exit();
283  }
284  } else {
285  header('HTTP/1.1 400 Improper Return Type');
286  exit();
287  }
288  }
289  } else {
290  header('HTTP/1.1 400 Missing Path Components');
291  exit();
292  }
293  }

References get_plugin_names().

Referenced by __construct().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_baseline_command()

CO_Basalt::_process_baseline_command (   $in_andisol_instance,
  $in_http_method,
  $in_command,
  $in_path = [],
  $in_query = [] 
)
protected

This runs our baseline command.

Returns
the HTTP response intermediate state, as an associative array.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases (ignored).
$in_http_methodREQUIRED: 'GET' or 'POST' are the only allowed values.
$in_commandREQUIRED: The command to execute.
$in_pathOPTIONAL: The REST path, as an array of strings. For the baseline, this should be exactly one element.
$in_queryOPTIONAL: The query parameters, as an associative array.

Definition at line 570 of file co_basalt.class.php.

575  {
576  $ret = [];
577 
578  // No command simply means list the plugins.
579  if (('GET' == $in_http_method) && (!isset($in_command) || !$in_command)) {
580  $ret = Array('plugins' => CO_Config::plugin_names());
581  array_unshift($ret['plugins'], $this->plugin_name());
582  } elseif ( ('GET' == $in_http_method) && ('ping' == $in_command) ) {
583  $ret = $this->_process_ping_command($in_andisol_instance, $in_path);
584  } elseif (('POST' == $in_http_method) && $this->_andisol_instance->god() && ('bulk-loader' == $in_command) && CO_Config::$enable_bulk_upload) { // This is the "bulk-loader." It is POST-only, you must be logged in as God, and the variable needs to be true in the config.
585  $ret = $this->_baseline_bulk_loader();
586  } elseif ('tokens' == $in_command) { // If we are viewing or editing the tokens, then we deal with that here.
587  $ret = $this->_process_token_command($in_andisol_instance, $in_http_method, $in_path, $in_query);
588  } elseif (('serverinfo' == $in_command) && $in_andisol_instance->god()) { // God can ask for information about the server.
589  $ret = $this->_process_serverinfo_command($in_andisol_instance, $in_http_method, $in_path, $in_query);
590  } elseif (('backup' == $in_command) && $in_andisol_instance->god() && ('GET' == $in_http_method)) { // God can ask for a backup of the server (open wide).
591  $ret = $this->_baseline_fetch_backup($in_andisol_instance);
592  } elseif (('handlers' == $in_command) && isset($in_path[0]) && trim($in_path[0])) {
593  $id_list = explode(',', trim($in_path[0]));
594  $id_list = array_map('intval', $id_list);
595  $handlers = [];
596  foreach ($id_list as $id) {
597  if (1 < $id) {
598  $class_name = $in_andisol_instance->get_data_access_class_by_id($id);
599  if ($class_name) {
600  $handler = self::_get_handler($class_name);
601  if ($handler) {
602  $ret[$handler][] = $id;
603  }
604  }
605  }
606  }
607  } elseif (('visibility' == $in_command) && $in_andisol_instance->logged_in()) {
608  if ('token' == trim($in_path[0])) {
609  $token = intval(trim($in_path[1]));
610  if ((0 <= $token) && $in_andisol_instance->i_have_this_token($token)) {
611  if (isset($in_query['users'])) {
612  $objects = $in_andisol_instance->get_all_user_objects_with_access($token);
613  if (count($objects)) {
614  $ret['token']['token'] = $token;
615  $ret['token']['user_ids'] = array_map(function($item){ return intval($item->id()); }, $objects);
616  }
617  } else {
618  $objects = $in_andisol_instance->get_all_login_objects_with_access($token);
619  if (count($objects)) {
620  $ret['token']['token'] = $token;
621  $ret['token']['login_ids'] = array_map(function($item){ return intval($item->id()); }, $objects);
622  }
623  }
624  } else {
625  header('HTTP/1.1 400 Invalid Token');
626  exit();
627  }
628  } else {
629  $id = intval(trim($in_path[0]));
630  // The ID must be generally valid, and we need to be able to see it.
631  if ((1 < $id) && $in_andisol_instance->can_i_see_this_data_record($id)) {
632  $record = $in_andisol_instance->get_single_data_record_by_id($id);
633 
634  if ($record) {
635  $read_login_records = $in_andisol_instance->get_all_login_objects_with_access($record->read_security_id);
636  $write_login_records = $in_andisol_instance->get_all_login_objects_with_access($record->write_security_id);
637  $ret['id']['id'] = $id;
638  $ret['id']['writeable'] = $record->user_can_write();
639  $read_login_records = array_map(function($item){ return intval($item->id()); }, $read_login_records);
640  $write_login_records = array_map(function($item){ return intval($item->id()); }, $write_login_records);
641 
642  if (count($write_login_records)) {
643  foreach ($write_login_records as $id) {
644  if (!in_array($id, $read_login_records)) {
645  $read_login_records[] = $id;
646  }
647  }
648 
649  sort($write_login_records);
650  sort($read_login_records);
651  }
652 
653  if (count($read_login_records)) {
654  $ret['id']['read_login_ids'] = $read_login_records;
655  }
656 
657  if (count($write_login_records)) {
658  $ret['id']['write_login_ids'] = $write_login_records;
659  }
660  }
661  } else {
662  header('HTTP/1.1 400 Invalid ID');
663  exit();
664  }
665  }
666  } elseif ('version' == $in_command) {
667  $ret['version'] = __BASALT_VERSION__;
668  } elseif ('search' == $in_command) {
669  // For a location search, all three of these need to be specified, and radius needs to be nonzero.
670  $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;
671  $longitude = isset($in_query) && is_array($in_query) && isset($in_query['search_longitude']) ? floatval($in_query['search_longitude']) : NULL;
672  $latitude = isset($in_query) && is_array($in_query) && isset($in_query['search_latitude']) ? floatval($in_query['search_latitude']) : NULL;
673 
674  $search_page_size = isset($in_query) && is_array($in_query) && isset($in_query['search_page_size']) ? abs(intval($in_query['search_page_size'])) : 0; // This is the size of a page of results (1-based result count. 0 is no page size).
675  $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 if search_page_size is 0. The page we are interested in (0-based. 0 is the first page).
676  $writeable = isset($in_query) && is_array($in_query) && isset($in_query['writeable']); // Show/list only things this user can modify.
677  $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.
678 
679  $search_array = [];
680 
681  if (isset($radius) && (0 < $radius) && isset($longitude) && isset($latitude)) {
682  $location_search = Array('radius' => $radius, 'longitude' => $longitude, 'latitude' => $latitude);
683  $search_array['location'] = $location_search;
684  }
685 
686  if (isset($search_name)) {
687  $search_array['name'] = Array($search_name, 'use_like' => 1);
688  }
689 
690  $tags = [];
691 
692  $has_tag = false;
693 
694  for ($tag = 0; $tag < 10; $tag++) {
695  $tag_string = 'search_tag'.$tag;
696  $tag_value = isset($in_query) && is_array($in_query) && isset($in_query[$tag_string]) ? trim($in_query[$tag_string]) : NULL;
697  if ($tag_value !== NULL) {
698  $has_tag = true;
699  }
700  $tags[] = $tag_value;
701  }
702 
703  // If there were any specified tags, we search by tag. Otherwise, we don't bother.
704  if ($has_tag) {
705  $search_array['tags'] = $tags;
706  $search_array['tags']['use_like'] = 1;
707  }
708 
709  $object_list = $in_andisol_instance->generic_search($search_array, false, $search_page_size, $search_page_number, $writeable);
710 
711  if (isset($object_list) && is_array($object_list) && count($object_list)) {
712  foreach ($object_list as $instance) {
713  $class_name = get_class($instance);
714 
715  if ($class_name) {
716  $handler = self::_get_handler($class_name);
717  $ret[$handler][] = $instance->id();
718  }
719  }
720  }
721 
722  if (isset($location_search)) {
723  $ret['search_location'] = $location_search;
724  }
725  }
726 
727  return $ret;
728  }
static _get_handler( $in_classname)
_process_ping_command( $in_andisol_instance, $in_path=[])
_process_serverinfo_command( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[])
_baseline_fetch_backup( $in_andisol_instance)
_process_token_command( $in_andisol_instance, $in_http_method, $in_path=[], $in_query=[])

References __BASALT_VERSION__, _baseline_bulk_loader(), _baseline_fetch_backup(), A_CO_Basalt_Plugin\_get_handler(), _process_ping_command(), _process_serverinfo_command(), _process_token_command(), and plugin_name().

Referenced by process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_bulk_row()

CO_Basalt::_process_bulk_row (   $in_row_data)
protected
Parameters
$in_row_dataREQUIRED: The associative array that describes this row. It is in

Definition at line 908 of file co_basalt.class.php.

909  {
910  $access_class = $in_row_data['access_class'];
911 
912  // Make sure that we don't step on any logins.
913  if ($this->_andisol_instance->check_login_exists_by_login_string($in_row_data['login_id'])) {
914  $in_row_data['login_id'] .= '-copy';
915  }
916 
917  $new_record = $this->_andisol_instance->make_new_blank_record($access_class);
918 
919  if (isset($new_record) && ($new_record instanceof $access_class)) {
920  $in_row_data['id'] = $new_record->id();
921  $new_record->set_batch_mode();
922  $new_record->load_from_db($in_row_data);
923  if (!$new_record->update_db()) {
924  header('HTTP/1.1 500 Internal Server Error');
925  exit();
926  }
927  return $new_record;
928  } else {
929  header('HTTP/1.1 400 Invalid Bulk Data');
930  exit();
931  }
932  }

Referenced by _baseline_bulk_loader().

Here is the caller graph for this function:

◆ _process_command()

CO_Basalt::_process_command ( )
protected

This runs our command.

Returns
the HTTP response string.

Definition at line 301 of file co_basalt.class.php.

301  {
302  $header = '';
303  $result = '';
304 
305  if (isset($this->_andisol_instance) && ($this->_andisol_instance instanceof CO_Andisol) && $this->_andisol_instance->valid()) {
306  if ('baseline' == $this->_plugin_selector) {
307  if (('GET' == $this->_request_type) || ('POST' == $this->_request_type)) {
308  $result = $this->process_command($this->_andisol_instance, $this->_request_type, $this->_response_type, $this->_path, $this->_vars);
309  } else {
310  $header = 'HTTP/1.1 400 Incorrect HTTP Request Method';
311  exit();
312  }
313  } else {
314  $plugin_filename = 'co_'.$this->_plugin_selector.'_basalt_plugin.class.php';
315  $plugin_classname = 'CO_'.$this->_plugin_selector.'_Basalt_Plugin';
316  $plugin_dirs = CO_Config::plugin_dirs();
317  $plugin_file = '';
318 
319  foreach ($plugin_dirs as $plugin_dir) {
320  if (isset($plugin_dir) && is_dir($plugin_dir)) {
321  // Iterate through that directory, and get each plugin directory.
322  foreach (new DirectoryIterator($plugin_dir) as $fileInfo) {
323  if ($plugin_filename == $fileInfo->getBasename()) {
324  $plugin_file = $fileInfo->getPathname();
325  break;
326  }
327  }
328  }
329  }
330 
331  if ($plugin_file) {
332  require_once($plugin_file);
333  $plugin_instance = new $plugin_classname();
334  if ($plugin_instance instanceof A_CO_Basalt_Plugin) {
335  $result = $plugin_instance->process_command($this->_andisol_instance, $this->_request_type, $this->_response_type, $this->_path, $this->_vars);
336  } else {
337  header('HTTP/1.1 400 Unsupported or Missing Plugin');
338  exit();
339  }
340  } else {
341  header('HTTP/1.1 400 Unsupported or Missing Plugin');
342  exit();
343  }
344  }
345 
346  switch ($this->_response_type) {
347  case 'xsd':
348  case 'xml':
349  $header .= 'Content-Type: text/xml';
350  break;
351 
352  case 'json':
353  $header .= 'Content-Type: application/json';
354  break;
355 
356  default:
357  $header = 'HTTP/1.1 400 Improper Return Type';
358  $result = '';
359  }
360  } else {
361  if (isset($this->_andisol_instance) && ($this->_andisol_instance instanceof CO_Andisol)) {
362  $this->error = $this->_andisol_instance->error;
363  if (isset($this->error) && ($this->error->error_code == CO_Lang_Common::$login_error_code_api_key_mismatch) || ($this->error->error_code == CO_Lang_Common::$pdo_error_code_invalid_login)) {
364  $header = 'HTTP/1.1 401 Unauthorized API Key';
365  } elseif (isset($this->error) && ($this->error->error_code == CO_Lang_Common::$login_error_code_api_key_invalid)) {
366  $header = 'HTTP/1.1 408 API Key Timeout';
367  } else {
368  $header = 'HTTP/1.1 400 General Error';
369  }
370  } else {
371  $header = 'HTTP/1.1 400 General Error';
372  }
373  }
374 
375  if ($header) {
376  header($header);
377  }
378 
379  $ob_stat = ob_get_status();
380  $use_ob = true;
381  if (is_array($ob_stat) && isset($ob_stat['level']) && 0 < $ob_stat['level']) {
382  $use_ob = false;
383  }
384 
385  if ($use_ob) {
386  $handler = null;
387 
388  if ( zlib_get_coding_type() === false )
389  {
390  $handler = "ob_gzhandler";
391  }
392 
393  ob_start($handler);
394  }
395 
396  if (is_array($result)) {
397  foreach ($result as $element) {
398  echo($element);
399  }
400  } else {
401  echo($result);
402  }
403 
404  if ($use_ob) {
405  ob_end_flush();
406  }
407  exit();
408  }
process_command( $in_andisol_instance, $in_http_method, $in_response_type, $in_path=[], $in_query=[])
static $pdo_error_code_invalid_login
Definition: common.inc.php:44
static $login_error_code_api_key_mismatch
Definition: common.inc.php:58
static $login_error_code_api_key_invalid
Definition: common.inc.php:57

References CO_Lang_Common\$login_error_code_api_key_invalid, CO_Lang_Common\$login_error_code_api_key_mismatch, CO_Lang_Common\$pdo_error_code_invalid_login, and process_command().

Referenced by __construct().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ _process_ping_command()

CO_Basalt::_process_ping_command (   $in_andisol_instance,
  $in_path = [] 
)
protected

This checks the login status of the IDs passed in. If no IDs, then it checks our own status.

Returns
the HTTP response intermediate state, as an associative array ([id => floating point number]).
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases (ignored).
$in_pathThis contains any IDs we are pinging. If omitted, then the current login is checked.

Definition at line 534 of file co_basalt.class.php.

536  {
537  $login_id_list = [];
538 
539  if ( isset ($in_path[0]) ) {
540  $login_id_list = array_map('intval', array_map('trim', explode(',', $in_path[0])));
541  } else {
542  $login_id_list = [$in_andisol_instance->current_login()->id()];
543  }
544  if ( 0 < count($login_id_list) ) {
545  $ret = [];
546 
547  foreach ($login_id_list as $id) {
548  $time = floatval($in_andisol_instance->get_remaining_time($id));
549 
550  if ( (-1 == $time) || (0 < $time) ) {
551  $ret["remaining_time"][] = ["id" => $id, "time" => $time];
552  }
553  }
554 
555  if ( 0 < count($ret) ) {
556  return $ret;
557  }
558  }
559 
560  header('HTTP/1.1 403 Unable to Determine Time');
561  exit();
562  }

Referenced by _process_baseline_command().

Here is the caller graph for this function:

◆ _process_serverinfo_command()

CO_Basalt::_process_serverinfo_command (   $in_andisol_instance,
  $in_http_method,
  $in_path = [],
  $in_query = [] 
)
protected

This runs our baseline serverinfo command.

Returns
the HTTP response intermediate state, as an associative array.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases (ignored).
$in_http_methodREQUIRED: 'GET' or 'POST' are the only allowed values.
$in_pathOPTIONAL: The REST path, as an array of strings. For the baseline, this should be exactly one element.
$in_queryOPTIONAL: The query parameters, as an associative array.

Definition at line 495 of file co_basalt.class.php.

499  {
500  $ret = NULL;
501  if ($in_andisol_instance->god()) { // We also have to be logged in as God to have any access to serverinfo.
502  $ret = ['serverinfo' => []];
503  $ret['serverinfo']['basalt_version'] = __BASALT_VERSION__;
504  $ret['serverinfo']['andisol_version'] = __ANDISOL_VERSION__;
505  $ret['serverinfo']['cobra_version'] = __COBRA_VERSION__;
506  $ret['serverinfo']['chameleon_version'] = __CHAMELEON_VERSION__;
507  $ret['serverinfo']['badger_version'] = __BADGER_VERSION__;
508  $ret['serverinfo']['security_db_type'] = CO_Config::$sec_db_type;
509  $ret['serverinfo']['data_db_type'] = CO_Config::$data_db_type;
510  $ret['serverinfo']['lang'] = CO_Config::$lang;
511  $ret['serverinfo']['min_pw_length'] = intval(CO_Config::$min_pw_len);
512  $ret['serverinfo']['regular_timeout_in_seconds'] = intval(CO_Config::$session_timeout_in_seconds);
513  $ret['serverinfo']['god_timeout_in_seconds'] = intval(CO_Config::$god_session_timeout_in_seconds);
514  $ret['serverinfo']['block_repeated_logins'] = CO_Config::$block_logins_for_valid_api_key ? true : false;
515  $ret['serverinfo']['block_differing_ip_address'] = CO_Config::$api_key_includes_ip_address ? true : false;
516  $ret['serverinfo']['ssl_requirement_level'] = intval(CO_Config::$ssl_requirement_level);
517  $ret['serverinfo']['google_api_key'] = CO_Config::$google_api_key;
518  $ret['serverinfo']['allow_address_lookup'] = CO_Config::$allow_address_lookup ? true : false;
519  $ret['serverinfo']['allow_general_address_lookup'] = CO_Config::$allow_general_address_lookup ? true : false;
520  $ret['serverinfo']['default_region_bias'] = CO_Config::$default_region_bias;
521  } else {
522  header('HTTP/1.1 403 Unauthorized Command');
523  exit();
524  }
525  return $ret;
526  }
const __ANDISOL_VERSION__
const __COBRA_VERSION__
const __CHAMELEON_VERSION__
const __BADGER_VERSION__

References $lang, __ANDISOL_VERSION__, __BADGER_VERSION__, __BASALT_VERSION__, __CHAMELEON_VERSION__, and __COBRA_VERSION__.

Referenced by _process_baseline_command().

Here is the caller graph for this function:

◆ _process_token_command()

CO_Basalt::_process_token_command (   $in_andisol_instance,
  $in_http_method,
  $in_path = [],
  $in_query = [] 
)
protected

This runs our baseline token command.

Returns
the HTTP response intermediate state, as an associative array.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases (ignored).
$in_http_methodREQUIRED: 'GET' or 'POST' are the only allowed values.
$in_pathOPTIONAL: The REST path, as an array of strings. For the baseline, this should be exactly one element.
$in_queryOPTIONAL: The query parameters, as an associative array.

Definition at line 416 of file co_basalt.class.php.

420  {
421  $ret = NULL;
422  if ($in_andisol_instance->logged_in()) { // We also have to be logged in to have any access to tokens.
423  if (('GET' == $in_http_method) && !isset($in_query['types']) && (!isset($in_path) || !is_array($in_path) || !count($in_path))) { // Do we just want a list of our tokens, or count access to a token?
424  $ret = ['tokens' => $in_andisol_instance->get_available_tokens()];
425  } elseif (('GET' == $in_http_method) && isset($in_query['types'])) { // If we added "types," then we want a catalog.
426  $tokens = $in_andisol_instance->get_available_tokens();
427  $personal_login_array = [];
428 
429  $ret_temp = [];
430  // If we are logged in as God, then we can actually get a list of the "owners" of personal tokens.
431  if ($in_andisol_instance->god()) {
432  $personal_login_array = $in_andisol_instance->get_logins_with_personal_ids();
433  } else { // If not God, then
434  $personal_login_array = [$in_andisol_instance->current_login()->id() => $in_andisol_instance->get_personal_security_ids()];
435  }
436 
437  foreach ($tokens as $token) {
438  $id = NULL;
439 
440  foreach ($personal_login_array as $key => $ids) {
441  if (in_array($token, $ids)) {
442  $id = $key;
443  break;
444  }
445  }
446 
447  $temp_ret = ['id' => $token];
448  if (isset($id)) {
449  $temp_ret['type'] = 'personal';
450  if ($in_andisol_instance->god()) {
451  $temp_ret['login_id'] = $id;
452  }
453  } elseif ($in_andisol_instance->is_this_a_personal_id($token)) { // This will tell us that we have the token, only on sufferance of someone else.
454  $temp_ret['type'] = 'assigned';
455  } elseif ($in_andisol_instance->is_this_a_login_id($token) && $in_andisol_instance->god()) { // Only God can know whether an ID is a login.
456  $temp_ret['type'] = 'login';
457  } else {
458  $temp_ret['type'] = 'token';
459  }
460 
461  $ret_temp[] = $temp_ret;
462  }
463  $ret['tokens'] = $ret_temp;
464  } elseif (('GET' == $in_http_method) && isset($in_query['count_access_to']) && (isset($in_path) && is_array($in_path) && count($in_path))) { // Ask for a response that counts all logins that have access to a given token.
465  $ids = array_map('trim', explode(',', $in_path[0]));
466  $ids = array_map('trim', $ids);
467  $ids = array_map('intval', $ids);
468  $ids = array_unique($ids);
469  $retTemp = [];
470  foreach ($ids as $single_id) {
471  if (1 < $single_id) { // We don't do 0 or 1
472  array_push($retTemp, ['token' => intval($single_id), 'access' => $in_andisol_instance->count_all_login_objects_with_access(intval($single_id))]);
473  }
474  }
475  $ret = ['count_access_to' => $retTemp];
476  } elseif (('POST' == $in_http_method) && $in_andisol_instance->manager()) { // If we are handling POST, then we ignore everything else, and create a new token. However, we need to be a manager to do this.
477  $ret = ['tokens' => [$in_andisol_instance->make_security_token()]];
478  } else {
479  header('HTTP/1.1 403 Unauthorized Command');
480  exit();
481  }
482  } else {
483  header('HTTP/1.1 403 Unauthorized Command');
484  exit();
485  }
486  return $ret;
487  }

Referenced by _process_baseline_command().

Here is the caller graph for this function:

◆ classes_managed()

static CO_Basalt::classes_managed ( )
static

This returns an array of classnames, handled by this plugin.

Returns
an array of string, with the names of the classes handled by this plugin.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 1172 of file co_basalt.class.php.

1172  {
1173  return [];
1174  }

◆ get_plugin_names()

CO_Basalt::get_plugin_names ( )
Returns
an array of strings, all lowercase, with the names of all the plugins used by BASALT.

Definition at line 1136 of file co_basalt.class.php.

1136  {
1137  $ret = CO_Config::plugin_names();
1138  array_unshift($ret, $this->plugin_name());
1139  return $ret;
1140  }

References plugin_name().

Referenced by _process_basalt_parameters().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ logged_in()

CO_Basalt::logged_in ( )
Returns
true, if the current user is successfully logged into the system.

Definition at line 1154 of file co_basalt.class.php.

1154  {
1155  return isset($this->_andisol_instance) ? $this->_andisol_instance->logged_in() : false;
1156  }

◆ plugin_name()

CO_Basalt::plugin_name ( )
Returns
a string, with our plugin name.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 1162 of file co_basalt.class.php.

1162  {
1163  return _PLUGIN_NAME_;
1164  }
const _PLUGIN_NAME_

References _PLUGIN_NAME_.

Referenced by _process_baseline_command(), and get_plugin_names().

Here is the caller graph for this function:

◆ process_command()

CO_Basalt::process_command (   $in_andisol_instance,
  $in_http_method,
  $in_response_type,
  $in_path = [],
  $in_query = [] 
)

This runs our baseline command.

Returns
the HTTP response string, as either JSON or XML.
Parameters
$in_andisol_instanceREQUIRED: The ANDISOL instance to use as the connection to the RVP databases (ignored).
$in_http_methodREQUIRED: 'GET' or 'POST' are the only allowed values.
$in_response_typeREQUIRED: 'json', 'csv', 'xml' or 'xsd' -the response type.
$in_pathOPTIONAL: The REST path, as an array of strings. For the baseline, this should be exactly one element.
$in_queryOPTIONAL: The query parameters, as an associative array.

Reimplemented from A_CO_Basalt_Plugin.

Definition at line 1182 of file co_basalt.class.php.

1187  {
1188  $ret = NULL;
1189 
1190  if (is_array($in_path) && (3 >= count($in_path))) {
1191  $command = isset($in_path[0]) ? strtolower(trim(array_shift($in_path))) : [];
1192  // Backup needs God Admin, GET method, and CSV response format.
1193  if ((('csv' == $in_response_type) && ('backup' != $command)) || (('backup' == $command) && (!$in_andisol_instance->god() || ('GET' != $in_http_method) || ('csv' != $in_response_type)))) {
1194  header('HTTP/1.1 400 Improper Baseline Command');
1195  exit();
1196  }
1197  $ret = $this->_process_baseline_command($in_andisol_instance, $in_http_method, $command, $in_path, $in_query);
1198  } else {
1199  header('HTTP/1.1 400 Improper Baseline Command');
1200  exit();
1201  }
1202 
1203  return $this->_condition_response($in_response_type, $ret);
1204  }
_condition_response( $in_response_type, $in_response_as_associative_array=NULL)
_process_baseline_command( $in_andisol_instance, $in_http_method, $in_command, $in_path=[], $in_query=[])

References A_CO_Basalt_Plugin\_condition_response(), and _process_baseline_command().

Referenced by _process_command().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ valid()

CO_Basalt::valid ( )
Returns
true, if we have an ANDISOL instance up and going.

Definition at line 1146 of file co_basalt.class.php.

1146  {
1147  return isset($this->_andisol_instance) ? $this->_andisol_instance->valid() : false;
1148  }

Member Data Documentation

◆ $_andisol_instance

CO_Basalt::$_andisol_instance
protected

This contains the instance of ANDISOL used by this instance.

Definition at line 56 of file co_basalt.class.php.

◆ $_path

CO_Basalt::$_path
protected

This array will contain any path components that are received via GET, PUT, POST or DELETE.

Definition at line 57 of file co_basalt.class.php.

◆ $_plugin_selector

CO_Basalt::$_plugin_selector
protected

This will be a lowercase string, denoting the plugin selected for the operation.

Definition at line 67 of file co_basalt.class.php.

◆ $_request_type

CO_Basalt::$_request_type
protected

This will contain the HTTP Request Type, in uppercase. It will be one of:

  • 'GET'
  • 'POST'
  • 'PUT'
  • 'DELETE'

Definition at line 59 of file co_basalt.class.php.

◆ $_response_type

CO_Basalt::$_response_type
protected

This is the reponse type. It is 'json', 'xml' or 'xsd'.

Definition at line 66 of file co_basalt.class.php.

◆ $_vars

CO_Basalt::$_vars
protected

This associative array will contain any query variables that are received via GET, PUT, POST or DELETE.

Definition at line 58 of file co_basalt.class.php.

◆ $error

CO_Basalt::$error

Any errors that occured are kept here.

Definition at line 70 of file co_basalt.class.php.

◆ $version

CO_Basalt::$version

The version indicator.

Definition at line 69 of file co_basalt.class.php.